OPC Studio User's Guide and Reference
Browsing for OPC Classic Nodes (Branches and Leaves)
Concepts > OPC Data Client Concepts > OPC Data Client Development Models > Imperative Programming Model > Imperative Programming Model for OPC Data (Classic and UA) > Browsing for Information (OPC Data) > Browsing for OPC Classic Nodes (Branches and Leaves)
In This Topic

OPC Address Space Organization

Items in an OPC server are typically organized in a tree hierarchy (address space), where the branch nodes serve organizational purposes (similar to folders in a file system), while the leaf nodes correspond to actual pieces of data that can be accessed (similar to files in a file system) – the OPC items. Each node has a “short” name that is unique among other branches or leaves under the same parent branch (or a root). Leaf nodes can be fully identified using a “long” ItemID, which determines the OPC item without a need to further qualify it with its position in the tree. ItemIDs may look like “Device1.Block101.Setpoint”, however their syntax and meaning is fully determined by the particular OPC server they are coming from.

Browse Methods

OPC Data Client gives you methods to traverse through the address space information and obtain the information available there. It is also possible to filter the returned nodes by various criteria, such as node name matching certain pattern, or a particular data type only, or writeable items only, etc.

If you want to retrieve a list of all sub-branches under a given branch (or under a root) of the OPC server, call the BrowseBranches method. You will receive back a DANodeElementCollection object. Each DANodeElement contains information gathered about one sub-branch node, such as its name, or indication whether it has children.

.NET

// This example shows how to obtain all branches at the root of the address space. For each branch, it displays whether 
// it may have child nodes.
//
// Find all latest examples here: https://opclabs.doc-that.com/files/onlinedocs/OPCLabs-OpcStudio/Latest/examples.html .
// OPC client and subscriber examples in C# on GitHub: https://github.com/OPCLabs/Examples-QuickOPC-CSharp .
// Missing some example? Ask us for it on our Online Forums, https://www.opclabs.com/forum/index ! You do not have to own
// a commercial license in order to use Online Forums, and we reply to every post.

using System;
using OpcLabs.EasyOpc.DataAccess;
using OpcLabs.EasyOpc.DataAccess.AddressSpace;
using OpcLabs.EasyOpc.OperationModel;

namespace DocExamples.DataAccess._EasyDAClient
{
    class BrowseBranches
    {
        public static void Main1()
        {
            // Instantiate the client object.
            var client = new EasyDAClient();
            DANodeElementCollection branchElements;
            try
            {
                branchElements = client.BrowseBranches("", "OPCLabs.KitServer.2", "");
            }
            catch (OpcException opcException)
            {
                Console.WriteLine("*** Failure: {0}", opcException.GetBaseException().Message);
                return;
            }

            foreach (DANodeElement branchElement in branchElements)
                Console.WriteLine($"BranchElements(\"{branchElement.Name}\").HasChildren: {branchElement.HasChildren}");
        }


        // Example output:
        //
        //BranchElements("$ServerControl").HasChildren: True
        //BranchElements("Boilers").HasChildren: True
        //BranchElements("Simulation").HasChildren: True
        //BranchElements("SimulateEvents").HasChildren: True
        //BranchElements("Trends").HasChildren: True
        //BranchElements("Demo").HasChildren: True
        //BranchElements("Greenhouse").HasChildren: True
    }
}
' This example shows how to obtain all branches at the root of the address space. For each branch, it displays whether 
' it may have child nodes.
'
' Find all latest examples here: https://opclabs.doc-that.com/files/onlinedocs/OPCLabs-OpcStudio/Latest/examples.html .
' OPC client and subscriber examples in VB.NET on GitHub: https://github.com/OPCLabs/Examples-QuickOPC-VBNET .
' Missing some example? Ask us for it on our Online Forums, https://www.opclabs.com/forum/index ! You do not have to own
' a commercial license in order to use Online Forums, and we reply to every post.

Imports OpcLabs.EasyOpc.DataAccess
Imports OpcLabs.EasyOpc.DataAccess.AddressSpace
Imports OpcLabs.EasyOpc.OperationModel

Namespace DataAccess._EasyDAClient
    Partial Friend Class BrowseBranches
        Shared Sub Main1()
            Dim client = New EasyDAClient()

            Dim branchElements As DANodeElementCollection
            Try
                branchElements = client.BrowseBranches("", "OPCLabs.KitServer.2", "")
            Catch opcException As OpcException
                Console.WriteLine("*** Failure: {0}", opcException.GetBaseException().Message)
                Exit Sub
            End Try

            For Each branchElement In branchElements
                Console.WriteLine($"BranchElements(""{branchElement.Name}"").HasChildren: {branchElement.HasChildren}")
            Next branchElement

        End Sub

        ' Example output
        '
        'BranchElements("$ServerControl").HasChildren: True
        'BranchElements("Boilers").HasChildren: True
        'BranchElements("Simulation").HasChildren: True
        'BranchElements("SimulateEvents").HasChildren: True
        'BranchElements("Trends").HasChildren: True
        'BranchElements("Demo").HasChildren: True
        'BranchElements("Greenhouse").HasChildren: True

    End Class
End Namespace

COM

Rem This example shows how to obtain all branches at the root of the address space. For each branch, it displays whether 
Rem it may have child nodes.
Rem
Rem Find all latest examples here: https://opclabs.doc-that.com/files/onlinedocs/OPCLabs-OpcStudio/Latest/examples.html .
Rem OPC client and subscriber examples in VBScript on GitHub: https://github.com/OPCLabs/Examples-QuickOPC-VBScript .
Rem Missing some example? Ask us for it on our Online Forums, https://www.opclabs.com/forum/index ! You do not have to own
Rem a commercial license in order to use Online Forums, and we reply to every post.

Option Explicit

Dim Client: Set Client = CreateObject("OpcLabs.EasyOpc.DataAccess.EasyDAClient")
On Error Resume Next
Dim BranchElements: Set BranchElements = Client.BrowseBranches("", "OPCLabs.KitServer.2", "")
If Err.Number <> 0 Then
    WScript.Echo "*** Failure: " & Err.Source & ": " & Err.Description
    WScript.Quit
End If
On Error Goto 0

Dim BranchElement: For Each BranchElement In BranchElements
    WScript.Echo "BranchElements(""" & BranchElement.Name & """).HasChildren: " & BranchElement.HasChildren
Next

Python

# This example shows how to obtain all branches at the root of the address space. For each branch, it displays whether
# it may have child nodes.
#
# Find all latest examples here: https://opclabs.doc-that.com/files/onlinedocs/OPCLabs-OpcStudio/Latest/examples.html .
# OPC client and subscriber examples in Python on GitHub: https://github.com/OPCLabs/Examples-QuickOPC-Python .
# Missing some example? Ask us for it on our Online Forums, https://www.opclabs.com/forum/index ! You do not have to own
# a commercial license in order to use Online Forums, and we reply to every post.
# The QuickOPC package is needed. Install it using "pip install opclabs_quickopc".
import opclabs_quickopc

# Import .NET namespaces.
from OpcLabs.EasyOpc.DataAccess import *
from OpcLabs.EasyOpc.OperationModel import *


# Instantiate the client object.
client = EasyDAClient()

# Perform the operation.
try:
    nodeElements = IEasyDAClientExtension.BrowseBranches(client, '', 'OPCLabs.KitServer.2', '')
except OpcException as opcException:
    print('*** Failure: ' + opcException.GetBaseException().Message)
    exit()

# Display results.
for nodeElement in nodeElements:
    print('NodeElements["', nodeElement.Name, '"].HasChildren: ', nodeElement.HasChildren, sep='')

 

Similarly, if you want to retrieve a list of leaves under a given branch (or under a root) of the OPC server, call the BrowseLeaves method. You will also receive back a DANodeElementCollection object, this time containing the leaves only. You can find information such as the Item ID from the DANodeElement of any leaf, and pass it further to methods like ReadItem or SubscribeItem.

.NET

// This example shows how to obtain all leaves under the "Simulation" branch of the address space. For each leaf, it displays 
// the ItemID of the node.
//
// Find all latest examples here: https://opclabs.doc-that.com/files/onlinedocs/OPCLabs-OpcStudio/Latest/examples.html .
// OPC client and subscriber examples in C# on GitHub: https://github.com/OPCLabs/Examples-QuickOPC-CSharp .
// Missing some example? Ask us for it on our Online Forums, https://www.opclabs.com/forum/index ! You do not have to own
// a commercial license in order to use Online Forums, and we reply to every post.

using System;
using OpcLabs.EasyOpc.DataAccess;
using OpcLabs.EasyOpc.DataAccess.AddressSpace;
using OpcLabs.EasyOpc.OperationModel;

namespace DocExamples.DataAccess._EasyDAClient
{
    class BrowseLeaves
    {
        public static void Main1()
        {
            // Instantiate the client object.
            var client = new EasyDAClient();
            DANodeElementCollection leafElements;
            try
            {
                leafElements = client.BrowseLeaves("", "OPCLabs.KitServer.2", "Simulation");
            }
            catch (OpcException opcException)
            {
                Console.WriteLine("*** Failure: {0}", opcException.GetBaseException().Message);
                return;
            }

            foreach (DANodeElement leafElement in leafElements)
                Console.WriteLine($"LeafElements(\"{leafElement.Name}\").ItemId: {leafElement.ItemId}");
        }


        // Example output:
        //
        //LeafElements("Register_ArrayOfI2").ItemId: Simulation.Register_ArrayOfI2
        //LeafElements("Register_ArrayOfI4").ItemId: Simulation.Register_ArrayOfI4
        //LeafElements("Staircase 0:2 (10 s)").ItemId: Simulation.Staircase 0:2 (10 s)
        //LeafElements("Constant_VARIANT").ItemId: Simulation.Constant_VARIANT
        //LeafElements("Staircase 0:10 (1 s)").ItemId: Simulation.Staircase 0:10 (1 s)
        //LeafElements("Register_DATE").ItemId: Simulation.Register_DATE
        //LeafElements("Constant_RECORD").ItemId: Simulation.Constant_RECORD
        //LeafElements("ReadValue_DECIMAL").ItemId: Simulation.ReadValue_DECIMAL
        //LeafElements("Ramp 0:360 (1 s)").ItemId: Simulation.Ramp 0:360 (1 s)
        //LeafElements("Constant_NULL").ItemId: Simulation.Constant_NULL
        //LeafElements("ReadValue_ArrayOfUI2").ItemId: Simulation.ReadValue_ArrayOfUI2
        //LeafElements("ReadValue_ArrayOfUI1").ItemId: Simulation.ReadValue_ArrayOfUI1
        //LeafElements("ReadValue_ArrayOfUI4").ItemId: Simulation.ReadValue_ArrayOfUI4
        //LeafElements("Constant_CY").ItemId: Simulation.Constant_CY
        //LeafElements("Staircase 0:2 (1 min)").ItemId: Simulation.Staircase 0:2 (1 min)
        //LeafElements("Staircase 0:2 (10 min)").ItemId: Simulation.Staircase 0:2 (10 min)
        //LeafElements("Square (10 s)").ItemId: Simulation.Square(10 s)
        //LeafElements("Register_ArrayOfBSTR").ItemId: Simulation.Register_ArrayOfBSTR
        //LeafElements("ReadValue_I2").ItemId: Simulation.ReadValue_I2
        //LeafElements("ReadValue_I1").ItemId: Simulation.ReadValue_I1
        //LeafElements("ReadValue_I4").ItemId: Simulation.ReadValue_I4
        //LeafElements("Ramp (1 s)").ItemId: Simulation.Ramp(1 s)
        //LeafElements("ReadValue_ArrayOfDATE").ItemId: Simulation.ReadValue_ArrayOfDATE
        //LeafElements("OnOff (1 s)").ItemId: Simulation.OnOff(1 s)
        //LeafElements("AlternatingQuality Uncertain (1 s)").ItemId: Simulation.AlternatingQuality Uncertain(1 s)
        //LeafElements("Register_NULL").ItemId: Simulation.Register_NULL
        //LeafElements("Random (1 min)").ItemId: Simulation.Random(1 min)
        //LeafElements("Random (10 min)").ItemId: Simulation.Random(10 min)
        //LeafElements("AlternatingError (10 s)").ItemId: Simulation.AlternatingError(10 s)
        //LeafElements("ReadValue_ArrayOfI1").ItemId: Simulation.ReadValue_ArrayOfI1
        //LeafElements("ReadValue_ArrayOfI2").ItemId: Simulation.ReadValue_ArrayOfI2
        //LeafElements("ReadValue_UI2").ItemId: Simulation.ReadValue_UI2
        //LeafElements("ReadValue_ArrayOfI4").ItemId: Simulation.ReadValue_ArrayOfI4
        //LeafElements("ReadValue_UI1").ItemId: Simulation.ReadValue_UI1
        //LeafElements("ReadValue_UI4").ItemId: Simulation.ReadValue_UI4
        //LeafElements("Weekdays (1 s)").ItemId: Simulation.Weekdays(1 s)
        //LeafElements("AlternatingQuality Uncertain (1 min)").ItemId: Simulation.AlternatingQuality Uncertain(1 min)
        //LeafElements("AlternatingQuality Uncertain (10 min)").ItemId: Simulation.AlternatingQuality Uncertain(10 min)
        //LeafElements("Weekdays (1 min)").ItemId: Simulation.Weekdays(1 min)
        //LeafElements("Weekdays (10 min)").ItemId: Simulation.Weekdays(10 min)
        //LeafElements("OnOff (10 s)").ItemId: Simulation.OnOff(10 s)
        //LeafElements("ReadWriteCount").ItemId: Simulation.ReadWriteCount
        //LeafElements("Register_UNKNOWN").ItemId: Simulation.Register_UNKNOWN
        //LeafElements("AlternatingQuality Uncertain (10 s)").ItemId: Simulation.AlternatingQuality Uncertain(10 s)
        //LeafElements("Constant_BSTR").ItemId: Simulation.Constant_BSTR
        //LeafElements("Constant_ERROR").ItemId: Simulation.Constant_ERROR
        //LeafElements("Constant_UI2").ItemId: Simulation.Constant_UI2
        //LeafElements("Constant_UI1").ItemId: Simulation.Constant_UI1
        //LeafElements("Constant_UI4").ItemId: Simulation.Constant_UI4
        //LeafElements("Constant_R4").ItemId: Simulation.Constant_R4
        //LeafElements("Constant_R8").ItemId: Simulation.Constant_R8
        //LeafElements("ReadValue_ArrayOfBSTR").ItemId: Simulation.ReadValue_ArrayOfBSTR
        //LeafElements("Register_ArrayOfR4").ItemId: Simulation.Register_ArrayOfR4
        //LeafElements("Register_ArrayOfR8").ItemId: Simulation.Register_ArrayOfR8
        //LeafElements("Ramp 0:360 (1 min)").ItemId: Simulation.Ramp 0:360 (1 min)
        //LeafElements("Ramp 0:360 (10 min)").ItemId: Simulation.Ramp 0:360 (10 min)
        //LeafElements("RegisterSet_n").ItemId: 
        //LeafElements("Register_ArrayOfUI4").ItemId: Simulation.Register_ArrayOfUI4
        //LeafElements("Register_ArrayOfUI1").ItemId: Simulation.Register_ArrayOfUI1
        //LeafElements("Register_ArrayOfUI2").ItemId: Simulation.Register_ArrayOfUI2
        //LeafElements("Register").ItemId: Simulation.Register
        //LeafElements("Constant_EMPTY").ItemId: Simulation.Constant_EMPTY
        //LeafElements("Register_RECORD").ItemId: Simulation.Register_RECORD
        //LeafElements("ReadValue_ArrayOfBOOL").ItemId: Simulation.ReadValue_ArrayOfBOOL
        //LeafElements("AlternatingError (1 min)").ItemId: Simulation.AlternatingError(1 min)
        //LeafElements("AlternatingError (10 min)").ItemId: Simulation.AlternatingError(10 min)
        //LeafElements("OnOff (1 min)").ItemId: Simulation.OnOff(1 min)
        //LeafElements("ReadValue_DATE").ItemId: Simulation.ReadValue_DATE
        //LeafElements("Register_ERROR").ItemId: Simulation.Register_ERROR
        //LeafElements("ReadValue_ArrayOfUINT").ItemId: Simulation.ReadValue_ArrayOfUINT
        //LeafElements("Incrementing (10 s)").ItemId: Simulation.Incrementing(10 s)
        //LeafElements("ReadValue_ArrayOfINT").ItemId: Simulation.ReadValue_ArrayOfINT
        //LeafElements("ReadValue_BOOL").ItemId: Simulation.ReadValue_BOOL
        //LeafElements("Register_ArrayOfCY").ItemId: Simulation.Register_ArrayOfCY
        //LeafElements("Incrementing (1 s)").ItemId: Simulation.Incrementing(1 s)
        //LeafElements("Constant_UINT").ItemId: Simulation.Constant_UINT
        //LeafElements("ReadValue_ArrayOfR4").ItemId: Simulation.ReadValue_ArrayOfR4
        //LeafElements("ReadValue_ArrayOfR8").ItemId: Simulation.ReadValue_ArrayOfR8
        //LeafElements("Constant_I4").ItemId: Simulation.Constant_I4
        //LeafElements("Constant_I2").ItemId: Simulation.Constant_I2
        //LeafElements("Constant_I1").ItemId: Simulation.Constant_I1
        //LeafElements("Register_BOOL").ItemId: Simulation.Register_BOOL
        //LeafElements("Constant_UNKNOWN").ItemId: Simulation.Constant_UNKNOWN
        //LeafElements("Ramp 0:100 (1 s)").ItemId: Simulation.Ramp 0:100 (1 s)
        //LeafElements("Register_UI4").ItemId: Simulation.Register_UI4
        //LeafElements("Register_UI2").ItemId: Simulation.Register_UI2
        //LeafElements("Register_UI1").ItemId: Simulation.Register_UI1
        //LeafElements("AlternatingError (1 s)").ItemId: Simulation.AlternatingError(1 s)
        //LeafElements("Sine (10 s)").ItemId: Simulation.Sine(10 s)
        //LeafElements("Constant_BOOL").ItemId: Simulation.Constant_BOOL
        //LeafElements("Sine -100:100 (10 s)").ItemId: Simulation.Sine -100:100 (10 s)
        //LeafElements("Register_UINT").ItemId: Simulation.Register_UINT
        //LeafElements("Constant").ItemId: Simulation.Constant
        //LeafElements("Sine (1 s)").ItemId: Simulation.Sine(1 s)
        //LeafElements("Register_I1").ItemId: Simulation.Register_I1
        //LeafElements("Register_I2").ItemId: Simulation.Register_I2
        //LeafElements("Register_I4").ItemId: Simulation.Register_I4
        //LeafElements("ReadValue_ArrayOfCY").ItemId: Simulation.ReadValue_ArrayOfCY
        //LeafElements("Register_ArrayOfUINT").ItemId: Simulation.Register_ArrayOfUINT
        //LeafElements("Incrementing (1 min)").ItemId: Simulation.Incrementing(1 min)
        //LeafElements("Weekdays (10 s)").ItemId: Simulation.Weekdays(10 s)
        //LeafElements("Square (1 s)").ItemId: Simulation.Square(1 s)
        //LeafElements("Sine (1 min)").ItemId: Simulation.Sine(1 min)
        //LeafElements("Sine (10 min)").ItemId: Simulation.Sine(10 min)
        //LeafElements("Constant_DISPATCH").ItemId: Simulation.Constant_DISPATCH
        //LeafElements("Ramp 0:100 (1 min)").ItemId: Simulation.Ramp 0:100 (1 min)
        //LeafElements("Ramp 0:100 (10 min)").ItemId: Simulation.Ramp 0:100 (10 min)
        //LeafElements("Random (1 s)").ItemId: Simulation.Random(1 s)
        //LeafElements("Staircase 0:10 (1 min)").ItemId: Simulation.Staircase 0:10 (1 min)
        //LeafElements("Staircase 0:10 (10 min)").ItemId: Simulation.Staircase 0:10 (10 min)
        //LeafElements("AlternatingQuality Bad (1 s)").ItemId: Simulation.AlternatingQuality Bad(1 s)
        //LeafElements("Sine -100:100 (1 s)").ItemId: Simulation.Sine -100:100 (1 s)
        //LeafElements("Register_ArrayOfDATE").ItemId: Simulation.Register_ArrayOfDATE
        //LeafElements("AlternatingQuality Bad (10 s)").ItemId: Simulation.AlternatingQuality Bad(10 s)
        //LeafElements("ReadValue_R4").ItemId: Simulation.ReadValue_R4
        //LeafElements("ReadValue_R8").ItemId: Simulation.ReadValue_R8
        //LeafElements("Ramp (1 min)").ItemId: Simulation.Ramp(1 min)
        //LeafElements("Ramp (10 min)").ItemId: Simulation.Ramp(10 min)
        //LeafElements("Register_DISPATCH").ItemId: Simulation.Register_DISPATCH
        //LeafElements("OnOff (10 min)").ItemId: Simulation.OnOff(10 min)
        //LeafElements("ReadValue_BSTR").ItemId: Simulation.ReadValue_BSTR
        //LeafElements("Staircase 0:10 (10 s)").ItemId: Simulation.Staircase 0:10 (10 s)
        //LeafElements("Random (10 s)").ItemId: Simulation.Random(10 s)
        //LeafElements("Incrementing").ItemId: Simulation.Incrementing
        //LeafElements("Register_BSTR").ItemId: Simulation.Register_BSTR
        //LeafElements("ReadValue_UINT").ItemId: Simulation.ReadValue_UINT
        //LeafElements("Register_CY").ItemId: Simulation.Register_CY
        //LeafElements("AlternatingQuality Bad (1 min)").ItemId: Simulation.AlternatingQuality Bad(1 min)
        //LeafElements("AlternatingQuality Bad (10 min)").ItemId: Simulation.AlternatingQuality Bad(10 min)
        //LeafElements("Random").ItemId: Simulation.Random
        //LeafElements("Sine -100:100 (1 min)").ItemId: Simulation.Sine -100:100 (1 min)
        //LeafElements("Sine -100:100 (10 min)").ItemId: Simulation.Sine -100:100 (10 min)
        //LeafElements("Ramp (10 s)").ItemId: Simulation.Ramp(10 s)
        //LeafElements("ReadValue_INT").ItemId: Simulation.ReadValue_INT
        //LeafElements("Staircase 0:2 (1 s)").ItemId: Simulation.Staircase 0:2 (1 s)
        //LeafElements("ReadValue_CY").ItemId: Simulation.ReadValue_CY
        //LeafElements("Register_R8").ItemId: Simulation.Register_R8
        //LeafElements("Register_R4").ItemId: Simulation.Register_R4
        //LeafElements("Register_DECIMAL").ItemId: Simulation.Register_DECIMAL
        //LeafElements("Incrementing (10 min)").ItemId: Simulation.Incrementing(10 min)
        //LeafElements("Register_EMPTY").ItemId: Simulation.Register_EMPTY
        //LeafElements("Constant_INT").ItemId: Simulation.Constant_INT
        //LeafElements("Register_INT").ItemId: Simulation.Register_INT
        //LeafElements("Register_ArrayOfBOOL").ItemId: Simulation.Register_ArrayOfBOOL
        //LeafElements("Ramp 0:100 (10 s)").ItemId: Simulation.Ramp 0:100 (10 s)
        //LeafElements("Ramp 0:360 (10 s)").ItemId: Simulation.Ramp 0:360 (10 s)
        //LeafElements("Square (1 min)").ItemId: Simulation.Square(1 min)
        //LeafElements("Square (10 min)").ItemId: Simulation.Square(10 min)
        //LeafElements("Constant_DECIMAL").ItemId: Simulation.Constant_DECIMAL
        //LeafElements("Register_VARIANT").ItemId: Simulation.Register_VARIANT
        //LeafElements("Constant_DATE").ItemId: Simulation.Constant_DATE
        //LeafElements("Register_ArrayOfINT").ItemId: Simulation.Register_ArrayOfINT
    }
}
' This example shows how to obtain all leaves under the "Simulation" branch of the address space. For each leaf, it displays 
' the ItemID of the node.
'
' Find all latest examples here: https://opclabs.doc-that.com/files/onlinedocs/OPCLabs-OpcStudio/Latest/examples.html .
' OPC client and subscriber examples in VB.NET on GitHub: https://github.com/OPCLabs/Examples-QuickOPC-VBNET .
' Missing some example? Ask us for it on our Online Forums, https://www.opclabs.com/forum/index ! You do not have to own
' a commercial license in order to use Online Forums, and we reply to every post.

Imports OpcLabs.EasyOpc.DataAccess
Imports OpcLabs.EasyOpc.DataAccess.AddressSpace
Imports OpcLabs.EasyOpc.OperationModel

Namespace DataAccess._EasyDAClient
    Partial Friend Class BrowseLeaves
        Shared Sub Main1()
            Dim client = New EasyDAClient()

            Dim leafElements As DANodeElementCollection
            Try
                leafElements = client.BrowseLeaves("", "OPCLabs.KitServer.2", "Simulation")
            Catch opcException As OpcException
                Console.WriteLine("*** Failure: {0}", opcException.GetBaseException().Message)
                Exit Sub
            End Try

            For Each leafElement In leafElements
                Console.WriteLine($"LeafElements(""{leafElement.Name}"").ItemId: {leafElement.ItemId}")
            Next leafElement

        End Sub

        ' Example output
        '
        'LeafElements("Register_ArrayOfI2").ItemId: Simulation.Register_ArrayOfI2
        'LeafElements("Register_ArrayOfI4").ItemId: Simulation.Register_ArrayOfI4
        'LeafElements("Staircase 0:2 (10 s)").ItemId: Simulation.Staircase 0:2 (10 s)
        'LeafElements("Constant_VARIANT").ItemId: Simulation.Constant_VARIANT
        'LeafElements("Staircase 0:10 (1 s)").ItemId: Simulation.Staircase 0:10 (1 s)
        'LeafElements("Register_DATE").ItemId: Simulation.Register_DATE
        'LeafElements("Constant_RECORD").ItemId: Simulation.Constant_RECORD
        'LeafElements("ReadValue_DECIMAL").ItemId: Simulation.ReadValue_DECIMAL
        'LeafElements("Ramp 0:360 (1 s)").ItemId: Simulation.Ramp 0:360 (1 s)
        'LeafElements("Constant_NULL").ItemId: Simulation.Constant_NULL
        'LeafElements("ReadValue_ArrayOfUI2").ItemId: Simulation.ReadValue_ArrayOfUI2
        'LeafElements("ReadValue_ArrayOfUI1").ItemId: Simulation.ReadValue_ArrayOfUI1
        'LeafElements("ReadValue_ArrayOfUI4").ItemId: Simulation.ReadValue_ArrayOfUI4
        'LeafElements("Constant_CY").ItemId: Simulation.Constant_CY
        'LeafElements("Staircase 0:2 (1 min)").ItemId: Simulation.Staircase 0:2 (1 min)
        'LeafElements("Staircase 0:2 (10 min)").ItemId: Simulation.Staircase 0:2 (10 min)
        'LeafElements("Square (10 s)").ItemId: Simulation.Square(10 s)
        'LeafElements("Register_ArrayOfBSTR").ItemId: Simulation.Register_ArrayOfBSTR
        'LeafElements("ReadValue_I2").ItemId: Simulation.ReadValue_I2
        'LeafElements("ReadValue_I1").ItemId: Simulation.ReadValue_I1
        'LeafElements("ReadValue_I4").ItemId: Simulation.ReadValue_I4
        'LeafElements("Ramp (1 s)").ItemId: Simulation.Ramp(1 s)
        'LeafElements("ReadValue_ArrayOfDATE").ItemId: Simulation.ReadValue_ArrayOfDATE
        'LeafElements("OnOff (1 s)").ItemId: Simulation.OnOff(1 s)
        'LeafElements("AlternatingQuality Uncertain (1 s)").ItemId: Simulation.AlternatingQuality Uncertain(1 s)
        'LeafElements("Register_NULL").ItemId: Simulation.Register_NULL
        'LeafElements("Random (1 min)").ItemId: Simulation.Random(1 min)
        'LeafElements("Random (10 min)").ItemId: Simulation.Random(10 min)
        'LeafElements("AlternatingError (10 s)").ItemId: Simulation.AlternatingError(10 s)
        'LeafElements("ReadValue_ArrayOfI1").ItemId: Simulation.ReadValue_ArrayOfI1
        'LeafElements("ReadValue_ArrayOfI2").ItemId: Simulation.ReadValue_ArrayOfI2
        'LeafElements("ReadValue_UI2").ItemId: Simulation.ReadValue_UI2
        'LeafElements("ReadValue_ArrayOfI4").ItemId: Simulation.ReadValue_ArrayOfI4
        'LeafElements("ReadValue_UI1").ItemId: Simulation.ReadValue_UI1
        'LeafElements("ReadValue_UI4").ItemId: Simulation.ReadValue_UI4
        'LeafElements("Weekdays (1 s)").ItemId: Simulation.Weekdays(1 s)
        'LeafElements("AlternatingQuality Uncertain (1 min)").ItemId: Simulation.AlternatingQuality Uncertain(1 min)
        'LeafElements("AlternatingQuality Uncertain (10 min)").ItemId: Simulation.AlternatingQuality Uncertain(10 min)
        'LeafElements("Weekdays (1 min)").ItemId: Simulation.Weekdays(1 min)
        'LeafElements("Weekdays (10 min)").ItemId: Simulation.Weekdays(10 min)
        'LeafElements("OnOff (10 s)").ItemId: Simulation.OnOff(10 s)
        'LeafElements("ReadWriteCount").ItemId: Simulation.ReadWriteCount
        'LeafElements("Register_UNKNOWN").ItemId: Simulation.Register_UNKNOWN
        'LeafElements("AlternatingQuality Uncertain (10 s)").ItemId: Simulation.AlternatingQuality Uncertain(10 s)
        'LeafElements("Constant_BSTR").ItemId: Simulation.Constant_BSTR
        'LeafElements("Constant_ERROR").ItemId: Simulation.Constant_ERROR
        'LeafElements("Constant_UI2").ItemId: Simulation.Constant_UI2
        'LeafElements("Constant_UI1").ItemId: Simulation.Constant_UI1
        'LeafElements("Constant_UI4").ItemId: Simulation.Constant_UI4
        'LeafElements("Constant_R4").ItemId: Simulation.Constant_R4
        'LeafElements("Constant_R8").ItemId: Simulation.Constant_R8
        'LeafElements("ReadValue_ArrayOfBSTR").ItemId: Simulation.ReadValue_ArrayOfBSTR
        'LeafElements("Register_ArrayOfR4").ItemId: Simulation.Register_ArrayOfR4
        'LeafElements("Register_ArrayOfR8").ItemId: Simulation.Register_ArrayOfR8
        'LeafElements("Ramp 0:360 (1 min)").ItemId: Simulation.Ramp 0:360 (1 min)
        'LeafElements("Ramp 0:360 (10 min)").ItemId: Simulation.Ramp 0:360 (10 min)
        'LeafElements("RegisterSet_n").ItemId: 
        'LeafElements("Register_ArrayOfUI4").ItemId Simulation.Register_ArrayOfUI4
        'LeafElements("Register_ArrayOfUI1").ItemId: Simulation.Register_ArrayOfUI1
        'LeafElements("Register_ArrayOfUI2").ItemId: Simulation.Register_ArrayOfUI2
        'LeafElements("Register").ItemId: Simulation.Register
        'LeafElements("Constant_EMPTY").ItemId: Simulation.Constant_EMPTY
        'LeafElements("Register_RECORD").ItemId: Simulation.Register_RECORD
        'LeafElements("ReadValue_ArrayOfBOOL").ItemId: Simulation.ReadValue_ArrayOfBOOL
        'LeafElements("AlternatingError (1 min)").ItemId: Simulation.AlternatingError(1 min)
        'LeafElements("AlternatingError (10 min)").ItemId: Simulation.AlternatingError(10 min)
        'LeafElements("OnOff (1 min)").ItemId: Simulation.OnOff(1 min)
        'LeafElements("ReadValue_DATE").ItemId: Simulation.ReadValue_DATE
        'LeafElements("Register_ERROR").ItemId: Simulation.Register_ERROR
        'LeafElements("ReadValue_ArrayOfUINT").ItemId: Simulation.ReadValue_ArrayOfUINT
        'LeafElements("Incrementing (10 s)").ItemId: Simulation.Incrementing(10 s)
        'LeafElements("ReadValue_ArrayOfINT").ItemId: Simulation.ReadValue_ArrayOfINT
        'LeafElements("ReadValue_BOOL").ItemId: Simulation.ReadValue_BOOL
        'LeafElements("Register_ArrayOfCY").ItemId: Simulation.Register_ArrayOfCY
        'LeafElements("Incrementing (1 s)").ItemId: Simulation.Incrementing(1 s)
        'LeafElements("Constant_UINT").ItemId: Simulation.Constant_UINT
        'LeafElements("ReadValue_ArrayOfR4").ItemId: Simulation.ReadValue_ArrayOfR4
        'LeafElements("ReadValue_ArrayOfR8").ItemId: Simulation.ReadValue_ArrayOfR8
        'LeafElements("Constant_I4").ItemId: Simulation.Constant_I4
        'LeafElements("Constant_I2").ItemId: Simulation.Constant_I2
        'LeafElements("Constant_I1").ItemId: Simulation.Constant_I1
        'LeafElements("Register_BOOL").ItemId: Simulation.Register_BOOL
        'LeafElements("Constant_UNKNOWN").ItemId: Simulation.Constant_UNKNOWN
        'LeafElements("Ramp 0:100 (1 s)").ItemId: Simulation.Ramp 0:100 (1 s)
        'LeafElements("Register_UI4").ItemId: Simulation.Register_UI4
        'LeafElements("Register_UI2").ItemId: Simulation.Register_UI2
        'LeafElements("Register_UI1").ItemId: Simulation.Register_UI1
        'LeafElements("AlternatingError (1 s)").ItemId: Simulation.AlternatingError(1 s)
        'LeafElements("Sine (10 s)").ItemId: Simulation.Sine(10 s)
        'LeafElements("Constant_BOOL").ItemId: Simulation.Constant_BOOL
        'LeafElements("Sine -100:100 (10 s)").ItemId: Simulation.Sine -100:100 (10 s)
        'LeafElements("Register_UINT").ItemId: Simulation.Register_UINT
        'LeafElements("Constant").ItemId: Simulation.Constant
        'LeafElements("Sine (1 s)").ItemId: Simulation.Sine(1 s)
        'LeafElements("Register_I1").ItemId: Simulation.Register_I1
        'LeafElements("Register_I2").ItemId: Simulation.Register_I2
        'LeafElements("Register_I4").ItemId: Simulation.Register_I4
        'LeafElements("ReadValue_ArrayOfCY").ItemId: Simulation.ReadValue_ArrayOfCY
        'LeafElements("Register_ArrayOfUINT").ItemId: Simulation.Register_ArrayOfUINT
        'LeafElements("Incrementing (1 min)").ItemId: Simulation.Incrementing(1 min)
        'LeafElements("Weekdays (10 s)").ItemId: Simulation.Weekdays(10 s)
        'LeafElements("Square (1 s)").ItemId: Simulation.Square(1 s)
        'LeafElements("Sine (1 min)").ItemId: Simulation.Sine(1 min)
        'LeafElements("Sine (10 min)").ItemId: Simulation.Sine(10 min)
        'LeafElements("Constant_DISPATCH").ItemId: Simulation.Constant_DISPATCH
        'LeafElements("Ramp 0:100 (1 min)").ItemId: Simulation.Ramp 0:100 (1 min)
        'LeafElements("Ramp 0:100 (10 min)").ItemId: Simulation.Ramp 0:100 (10 min)
        'LeafElements("Random (1 s)").ItemId: Simulation.Random(1 s)
        'LeafElements("Staircase 0:10 (1 min)").ItemId: Simulation.Staircase 0:10 (1 min)
        'LeafElements("Staircase 0:10 (10 min)").ItemId: Simulation.Staircase 0:10 (10 min)
        'LeafElements("AlternatingQuality Bad (1 s)").ItemId: Simulation.AlternatingQuality Bad(1 s)
        'LeafElements("Sine -100:100 (1 s)").ItemId: Simulation.Sine -100:100 (1 s)
        'LeafElements("Register_ArrayOfDATE").ItemId: Simulation.Register_ArrayOfDATE
        'LeafElements("AlternatingQuality Bad (10 s)").ItemId: Simulation.AlternatingQuality Bad(10 s)
        'LeafElements("ReadValue_R4").ItemId: Simulation.ReadValue_R4
        'LeafElements("ReadValue_R8").ItemId: Simulation.ReadValue_R8
        'LeafElements("Ramp (1 min)").ItemId: Simulation.Ramp(1 min)
        'LeafElements("Ramp (10 min)").ItemId: Simulation.Ramp(10 min)
        'LeafElements("Register_DISPATCH").ItemId: Simulation.Register_DISPATCH
        'LeafElements("OnOff (10 min)").ItemId: Simulation.OnOff(10 min)
        'LeafElements("ReadValue_BSTR").ItemId: Simulation.ReadValue_BSTR
        'LeafElements("Staircase 0:10 (10 s)").ItemId: Simulation.Staircase 0:10 (10 s)
        'LeafElements("Random (10 s)").ItemId: Simulation.Random(10 s)
        'LeafElements("Incrementing").ItemId: Simulation.Incrementing
        'LeafElements("Register_BSTR").ItemId: Simulation.Register_BSTR
        'LeafElements("ReadValue_UINT").ItemId: Simulation.ReadValue_UINT
        'LeafElements("Register_CY").ItemId: Simulation.Register_CY
        'LeafElements("AlternatingQuality Bad (1 min)").ItemId: Simulation.AlternatingQuality Bad(1 min)
        'LeafElements("AlternatingQuality Bad (10 min)").ItemId: Simulation.AlternatingQuality Bad(10 min)
        'LeafElements("Random").ItemId: Simulation.Random
        'LeafElements("Sine -100:100 (1 min)").ItemId: Simulation.Sine -100:100 (1 min)
        'LeafElements("Sine -100:100 (10 min)").ItemId: Simulation.Sine -100:100 (10 min)
        'LeafElements("Ramp (10 s)").ItemId: Simulation.Ramp(10 s)
        'LeafElements("ReadValue_INT").ItemId: Simulation.ReadValue_INT
        'LeafElements("Staircase 0:2 (1 s)").ItemId: Simulation.Staircase 0:2 (1 s)
        'LeafElements("ReadValue_CY").ItemId: Simulation.ReadValue_CY
        'LeafElements("Register_R8").ItemId: Simulation.Register_R8
        'LeafElements("Register_R4").ItemId: Simulation.Register_R4
        'LeafElements("Register_DECIMAL").ItemId: Simulation.Register_DECIMAL
        'LeafElements("Incrementing (10 min)").ItemId: Simulation.Incrementing(10 min)
        'LeafElements("Register_EMPTY").ItemId: Simulation.Register_EMPTY
        'LeafElements("Constant_INT").ItemId: Simulation.Constant_INT
        'LeafElements("Register_INT").ItemId: Simulation.Register_INT
        'LeafElements("Register_ArrayOfBOOL").ItemId: Simulation.Register_ArrayOfBOOL
        'LeafElements("Ramp 0:100 (10 s)").ItemId: Simulation.Ramp 0:100 (10 s)
        'LeafElements("Ramp 0:360 (10 s)").ItemId: Simulation.Ramp 0:360 (10 s)
        'LeafElements("Square (1 min)").ItemId: Simulation.Square(1 min)
        'LeafElements("Square (10 min)").ItemId: Simulation.Square(10 min)
        'LeafElements("Constant_DECIMAL").ItemId: Simulation.Constant_DECIMAL
        'LeafElements("Register_VARIANT").ItemId: Simulation.Register_VARIANT
        'LeafElements("Constant_DATE").ItemId: Simulation.Constant_DATE
        'LeafElements("Register_ArrayOfINT").ItemId: Simulation.Register_ArrayOfINT

    End Class
End Namespace

COM

Rem This example shows how to obtain all leaves under the "Simulation" branch of the address space. For each leaf, it displays 
Rem the ItemID of the node.
Rem
Rem Find all latest examples here: https://opclabs.doc-that.com/files/onlinedocs/OPCLabs-OpcStudio/Latest/examples.html .
Rem OPC client and subscriber examples in VBScript on GitHub: https://github.com/OPCLabs/Examples-QuickOPC-VBScript .
Rem Missing some example? Ask us for it on our Online Forums, https://www.opclabs.com/forum/index ! You do not have to own
Rem a commercial license in order to use Online Forums, and we reply to every post.

Option Explicit

Dim Client: Set Client = CreateObject("OpcLabs.EasyOpc.DataAccess.EasyDAClient")
On Error Resume Next
Dim LeafElements: Set LeafElements = Client.BrowseLeaves("", "OPCLabs.KitServer.2", "Simulation")
If Err.Number <> 0 Then
    WScript.Echo "*** Failure: " & Err.Source & ": " & Err.Description
    WScript.Quit
End If
On Error Goto 0

Dim LeafElement: For Each LeafElement In LeafElements
    WScript.Echo "LeafElements(""" & LeafElement.Name & """).ItemId: " & LeafElement.ItemId
Next

Python

# This example shows how to obtain all leaves under the "Simulation" branch of the address space. For each leaf, it
# displays the ItemID of the node.
#
# Find all latest examples here: https://opclabs.doc-that.com/files/onlinedocs/OPCLabs-OpcStudio/Latest/examples.html .
# OPC client and subscriber examples in Python on GitHub: https://github.com/OPCLabs/Examples-QuickOPC-Python .
# Missing some example? Ask us for it on our Online Forums, https://www.opclabs.com/forum/index ! You do not have to own
# a commercial license in order to use Online Forums, and we reply to every post.
# The QuickOPC package is needed. Install it using "pip install opclabs_quickopc".
import opclabs_quickopc

# Import .NET namespaces.
from OpcLabs.EasyOpc.DataAccess import *
from OpcLabs.EasyOpc.OperationModel import *


# Instantiate the client object.
client = EasyDAClient()

# Perform the operation.
try:
    nodeElements = IEasyDAClientExtension.BrowseLeaves(client, '', 'OPCLabs.KitServer.2', 'Simulation')
except OpcException as opcException:
    print('*** Failure: ' + opcException.GetBaseException().Message)
    exit()

# Display results.
for nodeElement in nodeElements:
    print('NodeElements["', nodeElement.Name, '"].ItemId: ', nodeElement.ItemId, sep='')

 

The most generic address space browsing method is BrowseNodes. It combines the functionality of BrowseBranches and BrowseLeaves, and it also allows the widest range of filtering options by passing in an argument of type DABrowseParameters, or individual arguments for data type filter and access rights filter.

.NET

// This example shows how to obtain all nodes under the "Simulation" branch of the address space. For each node, it displays
// whether the node is a branch or a leaf.
//
// Find all latest examples here: https://opclabs.doc-that.com/files/onlinedocs/OPCLabs-OpcStudio/Latest/examples.html .
// OPC client and subscriber examples in C# on GitHub: https://github.com/OPCLabs/Examples-QuickOPC-CSharp .
// Missing some example? Ask us for it on our Online Forums, https://www.opclabs.com/forum/index ! You do not have to own
// a commercial license in order to use Online Forums, and we reply to every post.

using System;
using OpcLabs.EasyOpc.DataAccess;
using OpcLabs.EasyOpc.DataAccess.AddressSpace;
using OpcLabs.EasyOpc.OperationModel;

namespace DocExamples.DataAccess._EasyDAClient
{
    partial class BrowseNodes
    {
        public static void Main1()
        {
            // Instantiate the client object.
            var client = new EasyDAClient();

            DANodeElementCollection nodeElements;
            try
            {
                nodeElements = client.BrowseNodes("", "OPCLabs.KitServer.2", "Greenhouse", DABrowseParameters.Default);
            }
            catch (OpcException opcException)
            {
                Console.WriteLine($"*** Failure: {opcException.GetBaseException().Message}");
                return;
            }

            foreach (DANodeElement nodeElement in nodeElements)
            {
                Console.WriteLine($"NodeElements(\"{nodeElement.Name}\"):");
                Console.WriteLine($"    .IsBranch: {nodeElement.IsBranch}");
                Console.WriteLine($"    .IsLeaf: {nodeElement.IsLeaf}");
            }
        }
    }
}
# This example shows how to obtain all nodes under the "Simulation" branch of the address space. For each node, it displays
# whether the node is a branch or a leaf.
#
# Find all latest examples here: https://opclabs.doc-that.com/files/onlinedocs/OPCLabs-OpcStudio/Latest/examples.html .
# OPC client and subscriber examples in PowerShell on GitHub: https://github.com/OPCLabs/Examples-QuickOPC-PowerShell .
# Missing some example? Ask us for it on our Online Forums, https://www.opclabs.com/forum/index ! You do not have to own
# a commercial license in order to use Online Forums, and we reply to every post.

#requires -Version 5.1
using namespace OpcLabs.EasyOpc.OperationModel
using namespace OpcLabs.EasyOpc.DataAccess

# The path below assumes that the current directory is [ProductDir]/Examples-NET/PowerShell/Windows .
Add-Type -Path "../../../Components/Opclabs.QuickOpc/net472/OpcLabs.EasyOpcClassicCore.dll"
Add-Type -Path "../../../Components/Opclabs.QuickOpc/net472/OpcLabs.EasyOpcClassic.dll"
Add-Type -Path "../../../Components/Opclabs.QuickOpc/net472/OpcLabs.EasyOpcClassicComponents.dll"

# Instantiate the client object.
$client = New-Object EasyDAClient

try {
    $nodeElements = [IEasyDAClientExtension]::BrowseNodes($client,
        "", "OPCLabs.KitServer.2", "Greenhouse", [DABrowseParameters]::Default)
}
catch [OpcException] {
    Write-Host "*** Failure: $($PSItem.Exception.GetBaseException().Message)"
    return
}

Foreach ($nodeElement in $nodeElements) {
    Write-Host "NodeElements(`"$($nodeElement.Name)`"):"
    Write-Host "    .IsBranch: $($nodeElement.IsBranch)"
    Write-Host "    .IsLeaf: $($nodeElement.IsLeaf)"
}
' This example shows how to obtain all nodes under the "Simulation" branch of the address space. For each node, it displays
' whether the node is a branch or a leaf.
'
' Find all latest examples here: https://opclabs.doc-that.com/files/onlinedocs/OPCLabs-OpcStudio/Latest/examples.html .
' OPC client and subscriber examples in VB.NET on GitHub: https://github.com/OPCLabs/Examples-QuickOPC-VBNET .
' Missing some example? Ask us for it on our Online Forums, https://www.opclabs.com/forum/index ! You do not have to own
' a commercial license in order to use Online Forums, and we reply to every post.

Imports OpcLabs.EasyOpc.DataAccess
Imports OpcLabs.EasyOpc.DataAccess.AddressSpace
Imports OpcLabs.EasyOpc.OperationModel

Namespace DataAccess._EasyDAClient
    Partial Friend Class BrowseNodes
        Shared Sub Main1()
            Dim client = New EasyDAClient()

            Dim nodeElements As DANodeElementCollection
            Try
                nodeElements = client.BrowseNodes("", "OPCLabs.KitServer.2", "Greenhouse", DABrowseParameters.Default)
            Catch opcException As OpcException
                Console.WriteLine("*** Failure: {0}", opcException.GetBaseException().Message)
                Exit Sub
            End Try

            For Each nodeElement In nodeElements
                Console.WriteLine($"NodeElements(""{nodeElement.Name}""):")
                Console.WriteLine($"    .IsBranch: {nodeElement.IsBranch}")
                Console.WriteLine($"    .IsLeaf: {nodeElement.IsLeaf}")
            Next nodeElement

        End Sub
    End Class
End Namespace

COM

// This example shows how to obtain all nodes under the "Simulation" branch of the address space. For each node, it displays
// whether the node is a branch or a leaf.
//
// Find all latest examples here: https://opclabs.doc-that.com/files/onlinedocs/OPCLabs-OpcStudio/Latest/examples.html .
// OPC client and subscriber examples in Object Pascal (Delphi) on GitHub: https://github.com/OPCLabs/Examples-QuickOPC-OP .
// Missing some example? Ask us for it on our Online Forums, https://www.opclabs.com/forum/index ! You do not have to own
// a commercial license in order to use Online Forums, and we reply to every post.

class procedure BrowseNodes.Main;
var
  BrowseParameters: _DABrowseParameters;
  Client: OpcLabs_EasyOpcClassic_TLB._EasyDAClient;
  Count: Cardinal;
  Element: OleVariant;
  ServerDescriptor: _ServerDescriptor;
  NodeDescriptor: _DANodeDescriptor;
  NodeElement: _DANodeElement;
  NodeElementEnumerator: IEnumVariant;
  NodeElements: _DANodeElementCollection;
begin
  ServerDescriptor := CoServerDescriptor.Create;
  ServerDescriptor.ServerClass := 'OPCLabs.KitServer.2';

  NodeDescriptor := CoDANodeDescriptor.Create;
  NodeDescriptor.ItemId := 'Simulation';

  BrowseParameters := CoDABrowseParameters.Create;

  // Instantiate the client object
  Client := CoEasyDAClient.Create;

  try
    NodeElements := Client.BrowseNodes(
      ServerDescriptor,
      NodeDescriptor,
      BrowseParameters);
  except
    on E: EOleException do
    begin
      WriteLn(Format('*** Failure: %s', [E.GetBaseException.Message]));
      Exit;
    end;
  end;

  NodeElementEnumerator := NodeElements.GetEnumerator;
  while (NodeElementEnumerator.Next(1, Element, Count) = S_OK) do
  begin
    NodeElement := IUnknown(Element) as _DANodeElement;
//    WriteLn(NodeElement.Name, ': ', NodeElement.ItemId);
    WriteLn('BrowseElements("', NodeElement.Name, '"):');
    WriteLn('    .IsBranch: ', NodeElement.IsBranch);
    WriteLn('    .IsLeaf: ', NodeElement.IsLeaf);
  end;
end;
// This example shows how to obtain all nodes under the "Simulation" branch of the address space. For each node, it displays
// whether the node is a branch or a leaf.
//
// Find all latest examples here: https://opclabs.doc-that.com/files/onlinedocs/OPCLabs-OpcStudio/Latest/examples.html .
// OPC client and subscriber examples in PHP on GitHub: https://github.com/OPCLabs/Examples-QuickOPC-PHP .
// Missing some example? Ask us for it on our Online Forums, https://www.opclabs.com/forum/index ! You do not have to own
// a commercial license in order to use Online Forums, and we reply to every post.

$ServerDescriptor = new COM("OpcLabs.EasyOpc.ServerDescriptor");
$ServerDescriptor->ServerClass = "OPCLabs.KitServer.2";

$NodeDescriptor = new COM("OpcLabs.EasyOpc.DataAccess.DANodeDescriptor");
$NodeDescriptor->ItemID = "Simulation";

$BrowseParameters = new COM("OpcLabs.EasyOpc.DataAccess.DABrowseParameters");

$Client = new COM("OpcLabs.EasyOpc.DataAccess.EasyDAClient");

try
{
    $NodeElements = $Client->BrowseNodes($ServerDescriptor, $NodeDescriptor, $BrowseParameters);
}
catch (com_exception $e)
{
    printf("*** Failure: %s\n", $e->getMessage());
    Exit();
}

foreach ($NodeElements as $NodeElement)
{
    printf("NodeElements(\"%s\"):\n", $NodeElement->Name);
    printf("    .IsBranch: %s\n", $NodeElement->IsBranch ? 'true' : 'false');
    printf("    .IsLeaf: %s\n", $NodeElement->IsLeaf ? 'true' : 'false');
}
// This example shows how to obtain all nodes under the "Simulation" branch of the address space. For each node, it displays
// whether the node is a branch or a leaf.
//
// Find all latest examples here: https://opclabs.doc-that.com/files/onlinedocs/OPCLabs-OpcStudio/Latest/examples.html .

mle_outputtext.Text = ""

// Instantiate the client object
OLEObject client
client = CREATE OLEObject
client.ConnectToNewObject("OpcLabs.EasyOpc.DataAccess.EasyDAClient")

// Prepare the arguments

OLEObject serverDescriptor
serverDescriptor = CREATE OLEObject
serverDescriptor.ConnectToNewObject("OpcLabs.EasyOpc.ServerDescriptor")
serverDescriptor.ServerClass = "OPCLabs.KitServer.2"

OLEObject nodeDescriptor
nodeDescriptor = CREATE OLEObject
nodeDescriptor.ConnectToNewObject("OpcLabs.EasyOpc.DataAccess.DANodeDescriptor")
nodeDescriptor.ItemID = "Simulation"

OLEObject browseParameters
browseParameters = CREATE OLEObject
browseParameters.ConnectToNewObject("OpcLabs.EasyOpc.DataAccess.DABrowseParameters")

// Perform the operation
OLEObject nodeElements
TRY
    nodeElements = client.BrowseNodes(serverDescriptor, nodeDescriptor, browseParameters)
CATCH (OLERuntimeError oleRuntimeError)
    mle_outputtext.Text = mle_outputtext.Text + "*** Failure: " + oleRuntimeError.Description + "~r~n"
    RETURN
END TRY

OLEObject nodeElementList
nodeElementList = nodeElements.ToList()

// Display results
Int i
FOR i = 0 TO nodeElementList.Count - 1
    OLEObject nodeElement
    nodeElement = nodeElementList.Item[i]
    mle_outputtext.Text = mle_outputtext.Text + 'NodeElements("' + nodeElement.Name + '"):' + "~r~n" 
    mle_outputtext.Text = mle_outputtext.Text + "    nodeElement.IsBranch: " + String(nodeElement.IsBranch) + "~r~n"
    mle_outputtext.Text = mle_outputtext.Text + "    nodeElement.IsLeaf: " + String(nodeElement.IsLeaf) + "~r~n"
NEXT

mle_outputtext.Text = mle_outputtext.Text + "~r~n" 
mle_outputtext.Text = mle_outputtext.Text + "Finished." + "~r~n" 
# This example shows how to obtain all nodes under the "Simulation" branch of the address space. For each node, it displays
# whether the node is a branch or a leaf.
#
# The Python for Windows (pywin32) extensions package is needed. Install it using "pip install pypiwin32".
# CAUTION: We now recommend using Python.NET package instead. Full set of examples with Python.NET is available!
#
# Find all latest examples here: https://opclabs.doc-that.com/files/onlinedocs/OPCLabs-OpcStudio/Latest/examples.html .
import win32com.client
from pywintypes import com_error

serverDescriptor = win32com.client.Dispatch('OpcLabs.EasyOpc.ServerDescriptor')
serverDescriptor.ServerClass = 'OPCLabs.KitServer.2'

nodeDescriptor = win32com.client.Dispatch('OpcLabs.EasyOpc.DataAccess.DANodeDescriptor')
nodeDescriptor.ItemID = 'Simulation'

browseParameters = win32com.client.Dispatch('OpcLabs.EasyOpc.DataAccess.DABrowseParameters')

# Instantiate the client object
client = win32com.client.Dispatch('OpcLabs.EasyOpc.DataAccess.EasyDAClient') 

# Perform the operation
try:
    nodeElements = client.BrowseNodes(serverDescriptor, nodeDescriptor, browseParameters)
except com_error as e:
    print('*** Failure: ' + e.args[2][1] + ': ' + e.args[2][2])
    exit()

# Display results
for nodeElement in nodeElements:
    print('NodeElements("' + nodeElement.Name + '"):')
    print('    .IsBranch:', nodeElement.IsBranch)
    print('    .IsLeaf:', nodeElement.IsLeaf)


# Example output:
#
#NodeElements("Register_ArrayOfI1"):
#    .IsBranch: False
#    .IsLeaf: True
#NodeElements("Register_ArrayOfI2"):
#    .IsBranch: False
#    .IsLeaf: True
#NodeElements("Register_ArrayOfI4"):
#    .IsBranch: False
#    .IsLeaf: True
#NodeElements("Staircase 0:2 (10 s)"):
#    .IsBranch: False
#    .IsLeaf: True
#NodeElements("Constant_VARIANT"):
#    .IsBranch: False
#    .IsLeaf: True
#...

REM This example shows how to obtain all nodes under the "Simulation" branch of the address space. For each node, it displays
REM whether the node is a branch or a leaf.
REM
REM Find all latest examples here: https://opclabs.doc-that.com/files/onlinedocs/OPCLabs-OpcStudio/Latest/examples.html .
REM OPC client and subscriber examples in Visual Basic on GitHub: https://github.com/OPCLabs/Examples-QuickOPC-VB .
REM Missing some example? Ask us for it on our Online Forums, https://www.opclabs.com/forum/index ! You do not have to own
REM a commercial license in order to use Online Forums, and we reply to every post.

Private Sub BrowseNodes_Main_Command_Click()
    OutputText = ""
    
    Dim serverDescriptor As New serverDescriptor
    serverDescriptor.ServerClass = "OPCLabs.KitServer.2"
    
    Dim nodeDescriptor As New DANodeDescriptor
    nodeDescriptor.itemId = "Simulation"
    
    Dim browseParameters As New DABrowseParameters
    
    ' Instantiate the client object
    Dim client As New EasyDAClient

    On Error Resume Next
    Dim nodeElements As DANodeElementCollection
    Set nodeElements = client.BrowseNodes(serverDescriptor, nodeDescriptor, browseParameters)
    If Err.Number <> 0 Then
        OutputText = OutputText & "*** Failure: " & Err.Source & ": " & Err.Description & vbCrLf
        Exit Sub
    End If
    On Error GoTo 0

    Dim nodeElement: For Each nodeElement In nodeElements
        OutputText = OutputText & "BrowseElements(""" & nodeElement.Name & """): " & nodeElement.itemId & vbCrLf
        OutputText = OutputText & "    .IsBranch: " & nodeElement.IsBranch & vbCrLf
        OutputText = OutputText & "    .IsLeaf: " & nodeElement.IsLeaf & vbCrLf
    Next
    
End Sub
Rem This example shows how to obtain all nodes under the "Simulation" branch of the address space. For each node, it displays
Rem whether the node is a branch or a leaf.
Rem
Rem Find all latest examples here: https://opclabs.doc-that.com/files/onlinedocs/OPCLabs-OpcStudio/Latest/examples.html .
Rem OPC client and subscriber examples in VBScript on GitHub: https://github.com/OPCLabs/Examples-QuickOPC-VBScript .
Rem Missing some example? Ask us for it on our Online Forums, https://www.opclabs.com/forum/index ! You do not have to own
Rem a commercial license in order to use Online Forums, and we reply to every post.

Option Explicit

Dim ServerDescriptor: Set ServerDescriptor = CreateObject("OpcLabs.EasyOpc.ServerDescriptor")
ServerDescriptor.ServerClass = "OPCLabs.KitServer.2"

Dim NodeDescriptor: Set NodeDescriptor = CreateObject("OpcLabs.EasyOpc.DataAccess.DANodeDescriptor")
NodeDescriptor.ItemID = "Simulation"

Dim BrowseParameters: Set BrowseParameters = CreateObject("OpcLabs.EasyOpc.DataAccess.DABrowseParameters")

Dim Client: Set Client= CreateObject("OpcLabs.EasyOpc.DataAccess.EasyDAClient")
On Error Resume Next
Dim NodeElements: Set NodeElements = Client.BrowseNodes(ServerDescriptor, NodeDescriptor, BrowseParameters)
If Err.Number <> 0 Then
    WScript.Echo "*** Failure: " & Err.Source & ": " & Err.Description
    WScript.Quit
End If
On Error Goto 0

Dim NodeElement: For Each NodeElement In NodeElements
    WScript.Echo "NodeElements(""" & NodeElement.Name & """):"
    With NodeElement
        WScript.Echo Space(4) & ".IsBranch: " & .IsBranch
        WScript.Echo Space(4) & ".IsLeaf: " & .IsLeaf
    End With
Next

Python

# This example shows how to obtain all nodes under the "Simulation" branch of the address space. For each node, it displays
# whether the node is a branch or a leaf.
#
# Find all latest examples here: https://opclabs.doc-that.com/files/onlinedocs/OPCLabs-OpcStudio/Latest/examples.html .
# OPC client and subscriber examples in Python on GitHub: https://github.com/OPCLabs/Examples-QuickOPC-Python .
# Missing some example? Ask us for it on our Online Forums, https://www.opclabs.com/forum/index ! You do not have to own
# a commercial license in order to use Online Forums, and we reply to every post.
# The QuickOPC package is needed. Install it using "pip install opclabs_quickopc".
import opclabs_quickopc

# Import .NET namespaces.
from OpcLabs.EasyOpc.DataAccess import *
from OpcLabs.EasyOpc.OperationModel import *


# Instantiate the client object
client = EasyDAClient()

# Perform the operation
try:
    nodeElements = IEasyDAClientExtension.BrowseNodes(client,
        '', 'OPCLabs.KitServer.2', 'Greenhouse', DABrowseParameters.Default)
except OpcException as opcException:
    print('*** Failure: ' + opcException.GetBaseException().Message)
    exit()

# Display results
for nodeElement in nodeElements:
    print('NodeElements("' + nodeElement.Name + '"):')
    print('    .IsBranch:', nodeElement.IsBranch)
    print('    .IsLeaf:', nodeElement.IsLeaf)


# Example output:
#
#NodeElements("Register_ArrayOfI1"):
#    .IsBranch: False
#    .IsLeaf: True
#NodeElements("Register_ArrayOfI2"):
#    .IsBranch: False
#    .IsLeaf: True
#NodeElements("Register_ArrayOfI4"):
#    .IsBranch: False
#    .IsLeaf: True
#NodeElements("Staircase 0:2 (10 s)"):
#    .IsBranch: False
#    .IsLeaf: True
#NodeElements("Constant_VARIANT"):
#    .IsBranch: False
#    .IsLeaf: True
#...

More Examples

Browse nodes recursively

.NET

// This example shows how to recursively browse the nodes in the OPC address space.
//
// Find all latest examples here: https://opclabs.doc-that.com/files/onlinedocs/OPCLabs-OpcStudio/Latest/examples.html .
// OPC client and subscriber examples in C# on GitHub: https://github.com/OPCLabs/Examples-QuickOPC-CSharp .
// Missing some example? Ask us for it on our Online Forums, https://www.opclabs.com/forum/index ! You do not have to own
// a commercial license in order to use Online Forums, and we reply to every post.

using System;
using System.Diagnostics;
using OpcLabs.EasyOpc;
using OpcLabs.EasyOpc.DataAccess;
using OpcLabs.EasyOpc.DataAccess.AddressSpace;
using OpcLabs.EasyOpc.OperationModel;

namespace DocExamples.DataAccess._EasyDAClient
{
    partial class BrowseNodes
    {
        public static void Recursive()
        {
            var stopwatch = new Stopwatch();
            stopwatch.Start();

            // Instantiate the client object.
            var client = new EasyDAClient();
            _branchCount = 0;
            _leafCount = 0;

            try
            {
                BrowseFromNode(client, "OPCLabs.KitServer.2", "");
            }
            catch (OpcException opcException)
            {
                Console.WriteLine("*** Failure: {0}", opcException.GetBaseException().Message);
                return;
            }

            stopwatch.Stop();
            Console.WriteLine("Browsing has taken (milliseconds): {0}", stopwatch.ElapsedMilliseconds);
            Console.WriteLine("Branch count: {0}", _branchCount);
            Console.WriteLine("Leaf count: {0}", _leafCount);
        }

        private static void BrowseFromNode(
            EasyDAClient client,
            ServerDescriptor serverDescriptor,
            DANodeDescriptor parentNodeDescriptor)
        {
            Debug.Assert(client != null);
            Debug.Assert(serverDescriptor != null);
            Debug.Assert(parentNodeDescriptor != null);

            // Obtain all node elements under parentNodeDescriptor
            var browseParameters = new DABrowseParameters();    // no filtering whatsoever
            DANodeElementCollection nodeElementCollection =
                client.BrowseNodes(serverDescriptor, parentNodeDescriptor, browseParameters);
            // Remark: that BrowseNodes(...) may also throw OpcException; a production code should contain handling for 
            // it, here omitted for brevity.

            foreach (DANodeElement nodeElement in nodeElementCollection)
            {
                Debug.Assert(nodeElement != null);

                Console.WriteLine(nodeElement);

                // If the node is a branch, browse recursively into it.
                if (nodeElement.IsBranch)
                {
                    _branchCount++;
                    BrowseFromNode(client, serverDescriptor, nodeElement);
                }
                else
                {
                    _leafCount++;
                }
            }
        }

        private static int _branchCount;
        private static int _leafCount;
    }
}
' This example shows how to recursively browse the nodes in the OPC address space.
'
' Find all latest examples here: https://opclabs.doc-that.com/files/onlinedocs/OPCLabs-OpcStudio/Latest/examples.html .
' OPC client and subscriber examples in VB.NET on GitHub: https://github.com/OPCLabs/Examples-QuickOPC-VBNET .
' Missing some example? Ask us for it on our Online Forums, https://www.opclabs.com/forum/index ! You do not have to own
' a commercial license in order to use Online Forums, and we reply to every post.

Imports OpcLabs.EasyOpc
Imports OpcLabs.EasyOpc.DataAccess
Imports OpcLabs.EasyOpc.DataAccess.AddressSpace
Imports OpcLabs.EasyOpc.OperationModel

Namespace DataAccess._EasyDAClient
    Partial Friend Class BrowseNodes

        Shared Sub Recursive()
            Dim stopwatch = New Stopwatch()
            stopwatch.Start()

            Dim client = New EasyDAClient()
            _branchCount = 0
            _leafCount = 0

            Try
                BrowseFromNode(client, "OPCLabs.KitServer.2", "")
            Catch opcException As OpcException
                Console.WriteLine("*** Failure: {0}", opcException.GetBaseException().Message)
                Exit Sub
            End Try

            stopwatch.Stop()
            Console.WriteLine("Browsing has taken (milliseconds): {0}", stopwatch.ElapsedMilliseconds)
            Console.WriteLine("Branch count: {0}", _branchCount)
            Console.WriteLine("Leaf count: {0}", _leafCount)
        End Sub

        Private Shared Sub BrowseFromNode( _
            client As EasyDAClient,
            serverDescriptor As ServerDescriptor,
            parentNodeDescriptor As DANodeDescriptor)

            Debug.Assert(client IsNot Nothing)
            Debug.Assert(serverDescriptor IsNot Nothing)
            Debug.Assert(parentNodeDescriptor IsNot Nothing)

            ' Obtain all node elements under parentNodeDescriptor
            Dim browseParameters = New DABrowseParameters() ' no filtering whatsoever
            Dim nodeElementCollection As DANodeElementCollection =
                client.BrowseNodes(serverDescriptor, parentNodeDescriptor, browseParameters)
            ' Remark: that BrowseNodes(...) may also throw OpcException; a production code should contain handling for 
            ' it, here omitted for brevity.

            For Each nodeElement As DANodeElement In nodeElementCollection
                Debug.Assert(nodeElement IsNot Nothing)

                Console.WriteLine(nodeElement)

                ' If the node is a branch, browse recursively into it.
                If nodeElement.IsBranch Then
                    _branchCount += 1
                    BrowseFromNode(client, serverDescriptor, nodeElement)
                Else
                    _leafCount += 1
                End If
            Next nodeElement
        End Sub

        Private Shared _branchCount As Integer
        Private Shared _leafCount As Integer
    End Class
End Namespace

Python

# This example shows how to recursively browse the nodes in the OPC address space.
#
# Find all latest examples here: https://opclabs.doc-that.com/files/onlinedocs/OPCLabs-OpcStudio/Latest/examples.html .
# OPC client and subscriber examples in Python on GitHub: https://github.com/OPCLabs/Examples-QuickOPC-Python .
# Missing some example? Ask us for it on our Online Forums, https://www.opclabs.com/forum/index ! You do not have to own
# a commercial license in order to use Online Forums, and we reply to every post.
# The QuickOPC package is needed. Install it using "pip install opclabs_quickopc".
import opclabs_quickopc
import timeit

# Import .NET namespaces.
from OpcLabs.EasyOpc import *
from OpcLabs.EasyOpc.DataAccess import *
from OpcLabs.EasyOpc.OperationModel import *


def browseFromNode(client, serverDescriptor, parentNodeDescriptor):
    global branchCount
    global leafCount

    assert client is not None
    assert serverDescriptor is not None
    assert parentNodeDescriptor is not None

    # Obtain all node elements under parentNodeDescriptor.
    browseParameters = DABrowseParameters() # no filtering whatsoever
    nodeElementCollection = client.BrowseNodes(serverDescriptor, parentNodeDescriptor, browseParameters)
    # BrowseNodes(...) may also throw OpcException; here it is handled by the caller.

    for nodeElement in nodeElementCollection:
        assert nodeElement is not None
        print(nodeElement)

        # If the node is a branch, browse recursively into it.
        if nodeElement.IsBranch:
            branchCount = branchCount + 1
            browseFromNode(client, serverDescriptor, DANodeDescriptor(nodeElement))
        else:
            leafCount = leafCount + 1


beginTime = timeit.default_timer()

# Instantiate the client object.
client = EasyDAClient()
branchCount = 0
leafCount = 0

try:
    browseFromNode(client, ServerDescriptor('OPCLabs.KitServer.2'), DANodeDescriptor(''))
except OpcException as opcException:
    print('*** Failure: ' + opcException.GetBaseException().Message)
    exit()

endTime = timeit.default_timer()
print()
print('Browsing has taken (milliseconds): ',(endTime - beginTime)*1000)
print('Branch count: ', branchCount);
print('Leaf count: ', leafCount);

Browse nodes recursively and read their values

.NET

// Recursively browses and displays the nodes in the OPC address space, and attempts to read and display values of all OPC 
// items it finds.
//
// Find all latest examples here: https://opclabs.doc-that.com/files/onlinedocs/OPCLabs-OpcStudio/Latest/examples.html .
// OPC client and subscriber examples in C# on GitHub: https://github.com/OPCLabs/Examples-QuickOPC-CSharp .
// Missing some example? Ask us for it on our Online Forums, https://www.opclabs.com/forum/index ! You do not have to own
// a commercial license in order to use Online Forums, and we reply to every post.

using System;
using System.Diagnostics;
using OpcLabs.EasyOpc.DataAccess;
using OpcLabs.EasyOpc.DataAccess.AddressSpace;
using OpcLabs.EasyOpc.OperationModel;

namespace DocExamples.DataAccess._EasyDAClient
{
    partial class BrowseNodes
    {
        const string ServerClass = "OPCLabs.KitServer.2";

        // Instantiate the client object.
        static readonly EasyDAClient Client = new EasyDAClient();

        static void BrowseAndReadFromNode(string parentItemId)
        {
            // Obtain all node elements under parentItemId
            var browseParameters = new DABrowseParameters(); // no filtering whatsoever
            DANodeElementCollection nodeElementCollection = Client.BrowseNodes("", ServerClass, parentItemId,
                browseParameters);
            // Remark: that BrowseNodes(...) may also throw OpcException; a production code should contain handling for it, here 
            // omitted for brevity.

            foreach (DANodeElement nodeElement in nodeElementCollection)
            {
                Debug.Assert(nodeElement != null);

                // If the node is a leaf, it might be possible to read from it
                if (nodeElement.IsLeaf)
                {
                    // Determine what the display - either the value read, or exception message in case of failure.
                    string display;
                    try
                    {
                        object value = Client.ReadItemValue("", ServerClass, nodeElement);
                        display = $"{value}";
                    }
                    catch (OpcException exception)
                    {
                        display = $"** {exception.GetBaseException().Message} **";
                    }

                    Console.WriteLine("{0} -> {1}", nodeElement.ItemId, display);
                }
                // If the node is not a leaf, just display its itemId
                else
                    Console.WriteLine("{0}", nodeElement.ItemId);

                // If the node is a branch, browse recursively into it.
                if (nodeElement.IsBranch &&
                    (nodeElement.ItemId != "SimulateEvents")
                    /* this branch is too big for the purpose of this example */)
                    BrowseAndReadFromNode(nodeElement);
            }
        }

        public static void RecursiveWithRead()
        {
            Console.WriteLine("Browsing and reading values...");
            // Set timeout to only wait 1 second - default would be 1 minute to wait for good quality that may never come.
            Client.InstanceParameters.Timeouts.ReadItem = 1000;

            // Do the actual browsing and reading, starting from root of OPC address space (denoted by empty string for itemId)
            try
            {
                BrowseAndReadFromNode("");
            }
            catch (OpcException opcException)
            {
                Console.WriteLine("*** Failure: {0}", opcException.GetBaseException().Message);
            }
        }
    }
}
' Recursively browses and displays the nodes in the OPC address space, and attempts to read and display values of all OPC 
' items it finds.
'
' Find all latest examples here: https://opclabs.doc-that.com/files/onlinedocs/OPCLabs-OpcStudio/Latest/examples.html .
' OPC client and subscriber examples in VB.NET on GitHub: https://github.com/OPCLabs/Examples-QuickOPC-VBNET .
' Missing some example? Ask us for it on our Online Forums, https://www.opclabs.com/forum/index ! You do not have to own
' a commercial license in order to use Online Forums, and we reply to every post.

Imports OpcLabs.EasyOpc.DataAccess
Imports OpcLabs.EasyOpc.DataAccess.AddressSpace
Imports OpcLabs.EasyOpc.OperationModel

Namespace DataAccess._EasyDAClient
    Partial Friend Class BrowseNodes
        Private Const ServerClass As String = "OPCLabs.KitServer.2"

        Private Shared ReadOnly Client As New EasyDAClient()

        Private Shared Sub BrowseAndReadFromNode(parentItemId As String)
            ' Obtain all node elements under parentItemId
            Dim browseParameters = New DABrowseParameters() ' no filtering whatsoever
            Dim nodeElementCollection As DANodeElementCollection = Client.BrowseNodes("", ServerClass, parentItemId, browseParameters)
            ' Remark: that BrowseNodes(...) may also throw OpcException; a production code should contain handling for it, here 
            ' omitted for brevity.

            For Each nodeElement As DANodeElement In nodeElementCollection
                Debug.Assert(nodeElement IsNot Nothing)

                ' If the node is a leaf, it might be possible to read from it
                If nodeElement.IsLeaf Then
                    ' Determine what the display - either the value read, or exception message in case of failure.
                    Dim display As String
                    Try
                        Dim value As Object = Client.ReadItemValue("", ServerClass, nodeElement.ItemId)
                        display = String.Format("{0}", value)
                    Catch exception As OpcException
                        display = String.Format("** {0} **", exception.GetBaseException().Message)
                    End Try

                    Console.WriteLine("{0} -> {1}", nodeElement.ItemId, display)
                    ' If the node is not a leaf, just display its itemId
                Else
                    Console.WriteLine("{0}", nodeElement.ItemId)
                End If

                ' If the node is a branch, browse recursively into it.
                If nodeElement.IsBranch AndAlso (nodeElement.ItemId <> "SimulateEvents") Then ' this branch is too big for the purpose of this example
                    BrowseAndReadFromNode(nodeElement.ItemId)
                End If
            Next nodeElement
        End Sub

        Shared Sub RecursiveWithRead()
            Console.WriteLine("Browsing and reading values...")
            ' Set timeout to only wait 1 second - default would be 1 minute to wait for good quality that may never come.
            Client.InstanceParameters.Timeouts.ReadItem = 1000

            ' Do the actual browsing and reading, starting from root of OPC address space (denoted by empty string for itemId)
            Try
                BrowseAndReadFromNode("")
            Catch opcException As OpcException
                Console.WriteLine("*** Failure: {0}", opcException.GetBaseException().Message)
                Exit Sub
            End Try
        End Sub
    End Class
End Namespace

Python

# Recursively browses and displays the nodes in the OPC address space, and attempts to read and display values of all
# OPC items it finds.
#
# Find all latest examples here: https://opclabs.doc-that.com/files/onlinedocs/OPCLabs-OpcStudio/Latest/examples.html .
# OPC client and subscriber examples in Python on GitHub: https://github.com/OPCLabs/Examples-QuickOPC-Python .
# Missing some example? Ask us for it on our Online Forums, https://www.opclabs.com/forum/index ! You do not have to own
# a commercial license in order to use Online Forums, and we reply to every post.
# The QuickOPC package is needed. Install it using "pip install opclabs_quickopc".
import opclabs_quickopc

# Import .NET namespaces.
from OpcLabs.EasyOpc import *
from OpcLabs.EasyOpc.DataAccess import *
from OpcLabs.EasyOpc.OperationModel import *

SERVER_CLASS = 'OPCLabs.KitServer.2'


def browseAndReadFromNode(parentItemId):
    global client
    #
    # Obtain all node elements under parentItemId.
    browseParameters = DABrowseParameters()  # no filtering whatsoever
    nodeElementCollection = client.BrowseNodes(ServerDescriptor(SERVER_CLASS),
                                               DANodeDescriptor(parentItemId),
                                               browseParameters)
    # BrowseNodes(...) may also throw OpcException; here it is handled by the caller.
    #
    for nodeElement in nodeElementCollection:
        assert nodeElement is not None
        print(nodeElement)

        # If the node is a leaf, it might be possible to read from it.
        if nodeElement.IsLeaf:
            # Determine what to display - either the value read, or exception message in case of failure.
            try:
                value = IEasyDAClientExtension.ReadItemValue(client, '', SERVER_CLASS, nodeElement.ItemId)
                display = value
            except OpcException as opcException:
                display = '** ' + opcException.GetBaseException().Message + ' **'
            #
            print(nodeElement.ItemId, ' -> ', display, sep='')
        # If the node is not a leaf, just display its itemId.
        else:
            print(nodeElement.ItemId)

        # If the node is a branch, browse recursively into it.
        if nodeElement.IsBranch and nodeElement.ItemId != 'SimulateEvents':
            # this branch is too big for the purpose of this example
            browseAndReadFromNode(nodeElement.ItemId)


# Instantiate the client object.
client = EasyDAClient('Browsing and reading values...')

print('Browsing and reading values...')

# Do the actual browsing and reading, starting from root of OPC address space (denoted by empty string for itemId).
try:
    browseAndReadFromNode('')
except OpcException as opcException:
    print('*** Failure: ' + opcException.GetBaseException().Message)
    exit()

print()
print('Finished.')

 

OPC XML-DA Examples

Browse for branches

.NET

// This example shows how to obtain all branches at the root of the address space. For each branch, it displays whether 
// it may have child nodes.
//
// Find all latest examples here: https://opclabs.doc-that.com/files/onlinedocs/OPCLabs-OpcStudio/Latest/examples.html .
// OPC client and subscriber examples in C# on GitHub: https://github.com/OPCLabs/Examples-QuickOPC-CSharp .
// Missing some example? Ask us for it on our Online Forums, https://www.opclabs.com/forum/index ! You do not have to own
// a commercial license in order to use Online Forums, and we reply to every post.

using System;
using OpcLabs.EasyOpc.DataAccess;
using OpcLabs.EasyOpc.DataAccess.AddressSpace;
using OpcLabs.EasyOpc.OperationModel;

namespace DocExamples.DataAccess.Xml
{
    class BrowseBranches
    {
        public static void Main1Xml()
        {
            // Instantiate the client object.
            var client = new EasyDAClient();
            DANodeElementCollection branchElements;
            try
            {
                branchElements = client.BrowseBranches("http://opcxml.demo-this.com/XmlDaSampleServer/Service.asmx");
            }
            catch (OpcException opcException)
            {
                Console.WriteLine("*** Failure: {0}", opcException.GetBaseException().Message);
                return;
            }

            foreach (DANodeElement branchElement in branchElements)
                Console.WriteLine($"BranchElements(\"{branchElement.Name}\").HasChildren: {branchElement.HasChildren}");
        }


        // Example output:
        //
        //BranchElements("Static").HasChildren: True
        //BranchElements("Dynamic").HasChildren: True
    }
}
' This example shows how to obtain all branches at the root of the address space. For each branch, it displays whether 
' it may have child nodes.
'
' Find all latest examples here: https://opclabs.doc-that.com/files/onlinedocs/OPCLabs-OpcStudio/Latest/examples.html .
' OPC client and subscriber examples in VB.NET on GitHub: https://github.com/OPCLabs/Examples-QuickOPC-VBNET .
' Missing some example? Ask us for it on our Online Forums, https://www.opclabs.com/forum/index ! You do not have to own
' a commercial license in order to use Online Forums, and we reply to every post.

Imports OpcLabs.EasyOpc.DataAccess
Imports OpcLabs.EasyOpc.DataAccess.AddressSpace
Imports OpcLabs.EasyOpc.OperationModel

Namespace DataAccess.Xml
    Partial Friend Class BrowseBranches
        Shared Sub Main1Xml()
            Dim client = New EasyDAClient()

            Dim branchElements As DANodeElementCollection
            Try
                branchElements = client.BrowseBranches("http://opcxml.demo-this.com/XmlDaSampleServer/Service.asmx")
            Catch opcException As OpcException
                Console.WriteLine("*** Failure: {0}", opcException.GetBaseException().Message)
                Exit Sub
            End Try

            For Each branchElement In branchElements
                Console.WriteLine($"BranchElements(""{branchElement.Name}"").HasChildren: {branchElement.HasChildren}")
            Next branchElement

        End Sub

        ' Example output
        '
        'BranchElements("Static").HasChildren: True
        'BranchElements("Dynamic").HasChildren: True

    End Class
End Namespace

Python

# This example shows how to obtain all branches at the root of the address space. For each branch, it displays whether 
# it may have child nodes.
#
# Find all latest examples here: https://opclabs.doc-that.com/files/onlinedocs/OPCLabs-OpcStudio/Latest/examples.html .
# OPC client and subscriber examples in Python on GitHub: https://github.com/OPCLabs/Examples-QuickOPC-Python .
# Missing some example? Ask us for it on our Online Forums, https://www.opclabs.com/forum/index ! You do not have to own
# a commercial license in order to use Online Forums, and we reply to every post.
# The QuickOPC package is needed. Install it using "pip install opclabs_quickopc".
import opclabs_quickopc

# Import .NET namespaces.
from OpcLabs.EasyOpc import *
from OpcLabs.EasyOpc.DataAccess import *
from OpcLabs.EasyOpc.DataAccess.AddressSpace import *
from OpcLabs.EasyOpc.OperationModel import *

# Instantiate the client object.
client = EasyDAClient()

try:
    branchElements = IEasyDAClientExtension.BrowseBranches(client, ServerDescriptor('http://opcxml.demo-this.com/XmlDaSampleServer/Service.asmx'))
except OpcException as opcException:
    print('*** Failure: ' + opcException.GetBaseException().Message, sep='')
    exit()

for branchElement in branchElements:
    print('BranchElements("', branchElement.Name, '").HasChildren: ', branchElement.HasChildren, sep='')

# Example output:
#
#BranchElements("Static").HasChildren: True
#BranchElements("Dynamic").HasChildren: True

 

OPC Data Client supports OPC XML-DA also on Linux and macOS.

Browse for leaves

.NET

// This example shows how to obtain all leaves under the "Simulation" branch of the address space. For each leaf, it displays 
// the ItemID of the node.
//
// Find all latest examples here: https://opclabs.doc-that.com/files/onlinedocs/OPCLabs-OpcStudio/Latest/examples.html .
// OPC client and subscriber examples in C# on GitHub: https://github.com/OPCLabs/Examples-QuickOPC-CSharp .
// Missing some example? Ask us for it on our Online Forums, https://www.opclabs.com/forum/index ! You do not have to own
// a commercial license in order to use Online Forums, and we reply to every post.

using System;
using OpcLabs.EasyOpc;
using OpcLabs.EasyOpc.DataAccess;
using OpcLabs.EasyOpc.DataAccess.AddressSpace;
using OpcLabs.EasyOpc.OperationModel;

namespace DocExamples.DataAccess.Xml
{
    class BrowseLeaves
    {
        public static void Main1Xml()
        {
            // Instantiate the client object.
            var client = new EasyDAClient();
            DANodeElementCollection leafElements;
            try
            {
                ServerDescriptor serverDescriptor = "http://opcxml.demo-this.com/XmlDaSampleServer/Service.asmx";
                leafElements = client.BrowseLeaves(serverDescriptor, "Static/Analog Types");
            }
            catch (OpcException opcException)
            {
                Console.WriteLine("*** Failure: {0}", opcException.GetBaseException().Message);
                return;
            }

            foreach (DANodeElement leafElement in leafElements)
                Console.WriteLine($"LeafElements(\"{leafElement.Name}\").ItemId: {leafElement.ItemId}");
        }


        // Example output:
        //
        //LeafElements("Int").ItemId: Static/Analog Types/Int
        //LeafElements("Double").ItemId: Static/Analog Types/Double
        //LeafElements("Int[]").ItemId: Static/Analog Types/Int[]
        //LeafElements("Double[]").ItemId: Static/Analog Types/Double[]
    }
}
' This example shows how to obtain all leaves under the "Simulation" branch of the address space. For each leaf, it displays 
' the ItemID of the node.
'
' Find all latest examples here: https://opclabs.doc-that.com/files/onlinedocs/OPCLabs-OpcStudio/Latest/examples.html .
' OPC client and subscriber examples in VB.NET on GitHub: https://github.com/OPCLabs/Examples-QuickOPC-VBNET .
' Missing some example? Ask us for it on our Online Forums, https://www.opclabs.com/forum/index ! You do not have to own
' a commercial license in order to use Online Forums, and we reply to every post.

Imports OpcLabs.EasyOpc
Imports OpcLabs.EasyOpc.DataAccess
Imports OpcLabs.EasyOpc.DataAccess.AddressSpace
Imports OpcLabs.EasyOpc.OperationModel

Namespace DataAccess.Xml
    Partial Friend Class BrowseLeaves
        Shared Sub Main1Xml()
            Dim client = New EasyDAClient()

            Dim leafElements As DANodeElementCollection
            Try
                Dim serverDescriptor As ServerDescriptor = "http://opcxml.demo-this.com/XmlDaSampleServer/Service.asmx"
                leafElements = client.BrowseLeaves(serverDescriptor, "Static/Analog Types")
            Catch opcException As OpcException
                Console.WriteLine("*** Failure: {0}", opcException.GetBaseException().Message)
                Exit Sub
            End Try

            For Each leafElement In leafElements
                Console.WriteLine($"LeafElements(""{leafElement.Name}"").ItemId: {leafElement.ItemId}")
            Next leafElement

        End Sub

        ' Example output
        '
        'LeafElements("Int").ItemId: Static/Analog Types/Int
        'LeafElements("Double").ItemId: Static/Analog Types/Double
        'LeafElements("Int[]").ItemId: Static/Analog Types/Int[]
        'LeafElements("Double[]").ItemId: Static/Analog Types/Double[]

    End Class
End Namespace

Python

# This example shows how to obtain all leaves under the "Simulation" branch of the address space. For each leaf, it displays 
# the ItemID of the node.
#
# Find all latest examples here: https://opclabs.doc-that.com/files/onlinedocs/OPCLabs-OpcStudio/Latest/examples.html .
# OPC client and subscriber examples in Python on GitHub: https://github.com/OPCLabs/Examples-QuickOPC-Python .
# Missing some example? Ask us for it on our Online Forums, https://www.opclabs.com/forum/index ! You do not have to own
# a commercial license in order to use Online Forums, and we reply to every post.
# The QuickOPC package is needed. Install it using "pip install opclabs_quickopc".
import opclabs_quickopc

# Import .NET namespaces.
from OpcLabs.EasyOpc import *
from OpcLabs.EasyOpc.DataAccess import *
from OpcLabs.EasyOpc.DataAccess.AddressSpace import *
from OpcLabs.EasyOpc.OperationModel import *

# Instantiate the client object.
client = EasyDAClient()

try:
    leafElements = IEasyDAClientExtension.BrowseLeaves(client, ServerDescriptor('http://opcxml.demo-this.com/XmlDaSampleServer/Service.asmx'), DANodeDescriptor('Static/Analog Types'))
except OpcException as opcException:
    print('*** Failure: ' + opcException.GetBaseException().Message, sep='')
    exit()

for leafElement in leafElements:
    print('LeafElements("', leafElement.Name, '").ItemId: ', leafElement.ItemId, sep='')

# Example output:
#
#LeafElements("Int").ItemId: Static/Analog Types/Int
#LeafElements("Double").ItemId: Static/Analog Types/Double
#LeafElements("Int[]").ItemId: Static/Analog Types/Int[]
#LeafElements("Double[]").ItemId: Static/Analog Types/Double[]

 

OPC Data Client supports OPC XML-DA also on Linux and macOS.

Browse nodes recursively

.NET

// This example shows how to recursively browse the nodes in the OPC XML-DA address space.
//
// Find all latest examples here: https://opclabs.doc-that.com/files/onlinedocs/OPCLabs-OpcStudio/Latest/examples.html .
// OPC client and subscriber examples in C# on GitHub: https://github.com/OPCLabs/Examples-QuickOPC-CSharp .
// Missing some example? Ask us for it on our Online Forums, https://www.opclabs.com/forum/index ! You do not have to own
// a commercial license in order to use Online Forums, and we reply to every post.

using System;
using System.Diagnostics;
using OpcLabs.EasyOpc;
using OpcLabs.EasyOpc.DataAccess;
using OpcLabs.EasyOpc.DataAccess.AddressSpace;
using OpcLabs.EasyOpc.OperationModel;

namespace DocExamples.DataAccess.Xml
{
    class BrowseNodes
    {
        public static void RecursiveXml()
        {
            var stopwatch = new Stopwatch();
            stopwatch.Start();

            // Instantiate the client object.
            var client = new EasyDAClient();

            _branchCount = 0;
            _leafCount = 0;

            try
            {
                BrowseFromNode(client, "http://opcxml.demo-this.com/XmlDaSampleServer/Service.asmx", "");
            }
            catch (OpcException opcException)
            {
                Console.WriteLine("*** Failure: {0}", opcException.GetBaseException().Message);
                return;
            }

            stopwatch.Stop();
            Console.WriteLine("Browsing has taken (milliseconds): {0}", stopwatch.ElapsedMilliseconds);
            Console.WriteLine("Branch count: {0}", _branchCount);
            Console.WriteLine("Leaf count: {0}", _leafCount);
        }

        private static void BrowseFromNode(
            EasyDAClient client,
            ServerDescriptor serverDescriptor,
            DANodeDescriptor parentNodeDescriptor)
        {
            Debug.Assert(client != null);
            Debug.Assert(serverDescriptor != null);
            Debug.Assert(parentNodeDescriptor != null);

            // Obtain all node elements under parentNodeDescriptor
            var browseParameters = new DABrowseParameters();    // no filtering whatsoever
            DANodeElementCollection nodeElementCollection =
                client.BrowseNodes(serverDescriptor, parentNodeDescriptor, browseParameters);
            // Remark: that BrowseNodes(...) may also throw OpcException; a production code should contain handling for 
            // it, here omitted for brevity.

            foreach (DANodeElement nodeElement in nodeElementCollection)
            {
                Debug.Assert(nodeElement != null);

                Console.WriteLine(nodeElement);

                // If the node is a branch, browse recursively into it.
                if (nodeElement.IsBranch)
                {
                    _branchCount++;
                    BrowseFromNode(client, serverDescriptor, nodeElement);
                }
                else
                {
                    _leafCount++;
                }
            }
        }

        private static int _branchCount;
        private static int _leafCount;
    }
}
' This example shows how to recursively browse the nodes in the OPC XML-DA address space.
'
' Find all latest examples here: https://opclabs.doc-that.com/files/onlinedocs/OPCLabs-OpcStudio/Latest/examples.html .
' OPC client and subscriber examples in VB.NET on GitHub: https://github.com/OPCLabs/Examples-QuickOPC-VBNET .
' Missing some example? Ask us for it on our Online Forums, https://www.opclabs.com/forum/index ! You do not have to own
' a commercial license in order to use Online Forums, and we reply to every post.

Imports OpcLabs.EasyOpc
Imports OpcLabs.EasyOpc.DataAccess
Imports OpcLabs.EasyOpc.DataAccess.AddressSpace
Imports OpcLabs.EasyOpc.OperationModel

Namespace DataAccess.Xml
    Partial Friend Class BrowseNodes

        Shared Sub RecursiveXml()
            Dim stopwatch = New Stopwatch()
            stopwatch.Start()

            Dim client = New EasyDAClient()
            _branchCount = 0
            _leafCount = 0

            Try
                BrowseFromNode(client, "http://opcxml.demo-this.com/XmlDaSampleServer/Service.asmx", "")
            Catch opcException As OpcException
                Console.WriteLine("*** Failure: {0}", opcException.GetBaseException().Message)
                Exit Sub
            End Try

            stopwatch.Stop()
            Console.WriteLine("Browsing has taken (milliseconds): {0}", stopwatch.ElapsedMilliseconds)
            Console.WriteLine("Branch count: {0}", _branchCount)
            Console.WriteLine("Leaf count: {0}", _leafCount)
        End Sub

        Private Shared Sub BrowseFromNode( _
            client As EasyDAClient,
            serverDescriptor As ServerDescriptor,
            parentNodeDescriptor As DANodeDescriptor)

            Debug.Assert(client IsNot Nothing)
            Debug.Assert(serverDescriptor IsNot Nothing)
            Debug.Assert(parentNodeDescriptor IsNot Nothing)

            ' Obtain all node elements under parentNodeDescriptor
            Dim browseParameters = New DABrowseParameters() ' no filtering whatsoever
            Dim nodeElementCollection As DANodeElementCollection =
                client.BrowseNodes(serverDescriptor, parentNodeDescriptor, browseParameters)
            ' Remark: that BrowseNodes(...) may also throw OpcException; a production code should contain handling for 
            ' it, here omitted for brevity.

            For Each nodeElement As DANodeElement In nodeElementCollection
                Debug.Assert(nodeElement IsNot Nothing)

                Console.WriteLine(nodeElement)

                ' If the node is a branch, browse recursively into it.
                If nodeElement.IsBranch Then
                    _branchCount += 1
                    BrowseFromNode(client, serverDescriptor, nodeElement)
                Else
                    _leafCount += 1
                End If
            Next nodeElement
        End Sub

        Private Shared _branchCount As Integer
        Private Shared _leafCount As Integer
    End Class
End Namespace

COM

// This example shows how to recursively browse the nodes in the OPC XML-DA address space.
//
// Find all latest examples here: https://opclabs.doc-that.com/files/onlinedocs/OPCLabs-OpcStudio/Latest/examples.html .
// OPC client and subscriber examples in Object Pascal (Delphi) on GitHub: https://github.com/OPCLabs/Examples-QuickOPC-OP .
// Missing some example? Ask us for it on our Online Forums, https://www.opclabs.com/forum/index ! You do not have to own
// a commercial license in order to use Online Forums, and we reply to every post.

type
  TBrowseNodes = class
    BranchCount: Integer;
    LeafCount: Integer;
    procedure BrowseFromNode(
      Client: OpcLabs_EasyOpcClassic_TLB._EasyDAClient;
      ServerDescriptor: _ServerDescriptor;
      ParentNodeDescriptor:  _DANodeDescriptor);
  end;

procedure TBrowseNodes.BrowseFromNode(
      Client: OpcLabs_EasyOpcClassic_TLB._EasyDAClient;
      ServerDescriptor: _ServerDescriptor;
      ParentNodeDescriptor: _DANodeDescriptor);
var
  BrowseParameters: _DABrowseParameters;
  Count: Cardinal;
  Element: OleVariant;
  NodeElement: _DANodeElement;
  NodeElementEnumerator: IEnumVariant;
  NodeElements: _DANodeElementCollection;
begin
  // Obtain all node elements under ParentNodeDescriptor
  BrowseParameters := CoDABrowseParameters.Create;  // no filtering whatsover
  NodeElements := Client.BrowseNodes(
    ServerDescriptor,
    ParentNodeDescriptor,
    BrowseParameters);
  // Remark: that BrowseNodes(...) may also throw OpcException; a production code should contain handling for 
  // it, here omitted for brevity.

  NodeElementEnumerator := NodeElements.GetEnumerator;
  while (NodeElementEnumerator.Next(1, Element, Count) = S_OK) do
  begin
    NodeElement := IUnknown(Element) as _DANodeElement;
    WriteLn(NodeElement.ToString);

    // If the node is a branch, browse recursively into it.
    if NodeElement.IsBranch then
    begin
      BranchCount := BranchCount + 1;
      BrowseFromNode(Client, ServerDescriptor, NodeElement.ToDANodeDescriptor);
    end
    else
      LeafCount := LeafCount + 1;
  end;
end;

class procedure BrowseNodes.RecursiveXml;
var
  BeginTime: Cardinal;
  BrowseNodes: TBrowseNodes;
  Client: OpcLabs_EasyOpcClassic_TLB._EasyDAClient;
  EndTime: Cardinal;
  ServerDescriptor: _ServerDescriptor;
  NodeDescriptor: _DANodeDescriptor;
begin
  BrowseNodes := TBrowseNodes.Create;
  BrowseNodes.BranchCount := 0;
  BrowseNodes.LeafCount := 0;

  BeginTime := Ticks;

  ServerDescriptor := CoServerDescriptor.Create;
  ServerDescriptor.UrlString := 'http://opcxml.demo-this.com/XmlDaSampleServer/Service.asmx';

  NodeDescriptor := CoDANodeDescriptor.Create;
  NodeDescriptor.ItemId := '';

  // Instantiate the client object
  Client := CoEasyDAClient.Create;

  try
    BrowseNodes.BrowseFromNode(
      Client,
      ServerDescriptor,
      NodeDescriptor);
  except
    on E: EOleException do
    begin
      WriteLn(Format('*** Failure: %s', [E.GetBaseException.Message]));
      Exit;
    end;
  end;

  EndTime := Ticks;

  WriteLn;
  WriteLn('Browsing has taken (milliseconds): ', (endTime - beginTime) * 1000);
  WriteLn('Branch count: ', BrowseNodes.BranchCount);
  WriteLn('Leaf count: ', BrowseNodes.LeafCount);
end;
// This example shows how to recursively browse the nodes in the OPC XML-DA address space.
//
// Find all latest examples here: https://opclabs.doc-that.com/files/onlinedocs/OPCLabs-OpcStudio/Latest/examples.html .
// OPC client and subscriber examples in PHP on GitHub: https://github.com/OPCLabs/Examples-QuickOPC-PHP .
// Missing some example? Ask us for it on our Online Forums, https://www.opclabs.com/forum/index ! You do not have to own
// a commercial license in order to use Online Forums, and we reply to every post.

$beginTime = microtime(true);
$branchCount = 0;
$leafCount = 0;

$ServerDescriptor = new COM("OpcLabs.EasyOpc.ServerDescriptor");
$ServerDescriptor->UrlString = "http://opcxml.demo-this.com/XmlDaSampleServer/Service.asmx";

$NodeDescriptor = new COM("OpcLabs.EasyOpc.DataAccess.DANodeDescriptor");
$NodeDescriptor->ItemID = "";

// Instantiate the client object.
$Client = new COM("OpcLabs.EasyOpc.DataAccess.EasyDAClient");

try
{
    BrowseFromNode($Client, $ServerDescriptor, $NodeDescriptor);
}
catch (com_exception $e)
{
    printf("*** Failure: %s\n", $e->getMessage());
    Exit();
}

$endTime = microtime(true);

printf("\n");
printf("Browsing has taken (milliseconds): : %f\n", ($endTime - $beginTime) * 1000);
printf("Branch count: %d\n", $branchCount);
printf("Leaf count: %d\n", $leafCount);


function BrowseFromNode($Client, $ServerDescriptor, $ParentNodeDescriptor) : void
{
    global $branchCount, $leafCount;

    // Obtain all node elements under ParentNodeDescriptor
    $BrowseParameters = new COM("OpcLabs.EasyOpc.DataAccess.DABrowseParameters"); // no filtering whatsoever
    $NodeElementCollection = $Client->BrowseNodes($ServerDescriptor, $ParentNodeDescriptor,$BrowseParameters);
    // Remark: that BrowseNodes(...) may also throw OpcException; a production code should contain handling for 
    //it, here omitted for brevity.

    foreach ($NodeElementCollection as $NodeElement)
    {
        printf("%s\n", $NodeElement);

        // If the node is a branch, browse recursively into it.
        if ($NodeElement->IsBranch)
        {
            $branchCount = $branchCount + 1;
            BrowseFromNode($Client, $ServerDescriptor, $NodeElement->ToDANodeDescriptor());
        }
        else
        {
            $leafCount = $leafCount + 1;
        }
    }
}
Rem This example shows how to recursively browse the nodes in the OPC XML-DA address space.
Rem
REM Find all latest examples here: https://opclabs.doc-that.com/files/onlinedocs/OPCLabs-OpcStudio/Latest/examples.html .
REM OPC client and subscriber examples in Visual Basic on GitHub: https://github.com/OPCLabs/Examples-QuickOPC-VB .
REM Missing some example? Ask us for it on our Online Forums, https://www.opclabs.com/forum/index ! You do not have to own
REM a commercial license in order to use Online Forums, and we reply to every post.

'Public branchCount As Integer
'Public leafCount As Integer

Private Sub BrowseNodes_RecursiveXml_Command_Click()
    OutputText = ""
    branchCount = 0
    leafCount = 0
    Dim beginTime: beginTime = Timer
        
    Dim serverDescriptor As New serverDescriptor
    serverDescriptor.UrlString = "http://opcxml.demo-this.com/XmlDaSampleServer/Service.asmx"
    
    Dim NodeDescriptor As New DANodeDescriptor
    NodeDescriptor.ItemId = ""
    
    ' Instantiate the client object
    Dim client As New EasyDAClient

    On Error Resume Next
        BrowseFromNode client, serverDescriptor, NodeDescriptor
    If Err.Number <> 0 Then
        OutputText = OutputText & "*** Failure: " & Err.Source & ": " & Err.Description & vbCrLf
        Exit Sub
    End If
    On Error GoTo 0

    Dim endTime: endTime = Timer
    
    OutputText = OutputText & vbCrLf
    OutputText = OutputText & "Browsing has taken (milliseconds): " & (endTime - beginTime) * 1000 & vbCrLf
    OutputText = OutputText & "Branch count: " & branchCount & vbCrLf
    OutputText = OutputText & "Leaf count: " & leafCount & vbCrLf
End Sub

Public Sub BrowseFromNode(client, serverDescriptor, ParentNodeDescriptor)
    ' Obtain all node elements under ParentNodeDescriptor
    Dim BrowseParameters As New DABrowseParameters
    Dim NodeElementCollection As DANodeElementCollection
    Set NodeElementCollection = client.BrowseNodes(serverDescriptor, ParentNodeDescriptor, BrowseParameters)
    ' Remark: that BrowseNodes(...) may also throw OpcException; a production code should contain handling for
    ' it, here omitted for brevity.

    Dim NodeElement: For Each NodeElement In NodeElementCollection
        OutputText = OutputText & NodeElement & vbCrLf
        
        ' If the node is a branch, browse recursively into it.
        If NodeElement.IsBranch Then
            branchCount = branchCount + 1
            BrowseFromNode client, serverDescriptor, NodeElement.ToDANodeDescriptor
        Else
            leafCount = leafCount + 1
        End If
    Next
End Sub
Rem This example shows how to recursively browse the nodes in the OPC XML-DA address space.
Rem
Rem Find all latest examples here: https://opclabs.doc-that.com/files/onlinedocs/OPCLabs-OpcStudio/Latest/examples.html .
Rem OPC client and subscriber examples in VBScript on GitHub: https://github.com/OPCLabs/Examples-QuickOPC-VBScript .
Rem Missing some example? Ask us for it on our Online Forums, https://www.opclabs.com/forum/index ! You do not have to own
Rem a commercial license in order to use Online Forums, and we reply to every post.

Option Explicit

Dim beginTime: beginTime = Timer
Dim branchCount: branchCount = 0
Dim leafCount: leafCount = 0

Dim ServerDescriptor: Set ServerDescriptor = CreateObject("OpcLabs.EasyOpc.ServerDescriptor")
ServerDescriptor.UrlString = "http://opcxml.demo-this.com/XmlDaSampleServer/Service.asmx"

Dim NodeDescriptor: Set NodeDescriptor = CreateObject("OpcLabs.EasyOpc.DataAccess.DANodeDescriptor")
NodeDescriptor.ItemID = ""

Dim Client: Set Client = CreateObject("OpcLabs.EasyOpc.DataAccess.EasyDAClient")
On Error Resume Next
BrowseFromNode Client, ServerDescriptor, NodeDescriptor
If Err.Number <> 0 Then
    WScript.Echo "*** Failure: " & Err.Source & ": " & Err.Description
    WScript.Quit
End If
On Error Goto 0

Dim endTime: endTime = Timer

WScript.Echo ""
WScript.Echo "Browsing has taken (milliseconds): " & (endTime - beginTime) * 1000
WScript.Echo "Branch count: " & branchCount
WScript.Echo "Leaf count: " & leafCount


Sub BrowseFromNode(Client, ServerDescriptor, ParentNodeDescriptor)
    ' Obtain all node elements under ParentNodeDescriptor
    Dim BrowseParameters: Set BrowseParameters = CreateObject("OpcLabs.EasyOpc.DataAccess.DABrowseParameters")
    Dim NodeElementCollection: Set NodeElementCollection = Client.BrowseNodes(serverDescriptor, parentNodeDescriptor, browseParameters)
    ' Remark: that BrowseNodes(...) may also throw OpcException; a production code should contain handling for 
    ' it, here omitted for brevity.

    Dim NodeElement: For Each NodeElement In NodeElementCollection
        WScript.Echo NodeElement
        
        ' If the node is a branch, browse recursively into it.
        If NodeElement.IsBranch Then
            branchCount = branchCount + 1
            BrowseFromNode Client, ServerDescriptor, NodeElement.ToDANodeDescriptor
        Else
            leafCount = leafCount + 1
        End If
    Next

End Sub

Python

# This example shows how to recursively browse the nodes in the OPC XML-DA address space.
#
# Find all latest examples here: https://opclabs.doc-that.com/files/onlinedocs/OPCLabs-OpcStudio/Latest/examples.html .
# OPC client and subscriber examples in Python on GitHub: https://github.com/OPCLabs/Examples-QuickOPC-Python .
# Missing some example? Ask us for it on our Online Forums, https://www.opclabs.com/forum/index ! You do not have to own
# a commercial license in order to use Online Forums, and we reply to every post.
# The QuickOPC package is needed. Install it using "pip install opclabs_quickopc".
import opclabs_quickopc
import timeit

# Import .NET namespaces.
from OpcLabs.EasyOpc import *
from OpcLabs.EasyOpc.DataAccess import *
from OpcLabs.EasyOpc.OperationModel import *


def browseFromNode(client, serverDescriptor, parentNodeDescriptor):
    global branchCount
    global leafCount

    assert client is not None
    assert serverDescriptor is not None
    assert parentNodeDescriptor is not None

    # Obtain all node elements under parentNodeDescriptor.
    browseParameters = DABrowseParameters() # no filtering whatsoever
    nodeElementCollection = client.BrowseNodes(serverDescriptor, parentNodeDescriptor, browseParameters)
    # BrowseNodes(...) may also throw OpcException; here it is handled by the caller.

    for nodeElement in nodeElementCollection:
        assert nodeElement is not None
        print(nodeElement)

        # If the node is a branch, browse recursively into it.
        if nodeElement.IsBranch:
            branchCount = branchCount + 1
            browseFromNode(client, serverDescriptor, DANodeDescriptor(nodeElement))
        else:
            leafCount = leafCount + 1


beginTime = timeit.default_timer()

# Instantiate the client object.
client = EasyDAClient()
branchCount = 0
leafCount = 0

try:
    browseFromNode(client,
                   ServerDescriptor('http://opcxml.demo-this.com/XmlDaSampleServer/Service.asmx'),
                   DANodeDescriptor(''))
except OpcException as opcException:
    print('*** Failure: ' + opcException.GetBaseException().Message)
    exit()

endTime = timeit.default_timer()
print()
print('Browsing has taken (milliseconds): ',(endTime - beginTime)*1000)
print('Branch count: ', branchCount);
print('Leaf count: ', leafCount);

 

OPC Data Client supports OPC XML-DA also on Linux and macOS.

 

See Also

Installed Examples - Client Web

Examples - Client OPC Data Access

Examples - Client OPC XML-DA